0

我有一些事件,人们。它们之间存在多对多的关系,因此有一个 PersonEvent 将事件连接到人。

事件有日期和类型

PersonEvent 有一个 event_id 和一个 person_id

人有名字

我正在尝试构建一个搜索表单,允许用户按活动类型进行搜索,然后返回过去参加过该类型活动的人员列表以及他们参加此类活动的最后日期。这应该在控制器中。

我能想到的唯一解决方案涉及嵌套循环,并且可能会运行得很慢。我肯定会遍历很多我不需要的东西。

For each person in Person.all
    For each personevent in PersonEvent.all
        Add the personevent to an array if the person_event.event.type is correct
    Now, loop through the array and find the event with the latest date. That's the date of the last Event attendance.

任何人都可以提出更好的算法吗?

4

3 回答 3

3

在 RoR 中,它将是:

Person.joins(:events).where(events: { type: params[:type] })

Railsjoins将创建一个INNER JOIN,它将丢弃没有符合where.

您没有解释如何保存出勤信息的日期,所以我将把这一点留给您。

于 2013-07-17T16:10:48.563 回答
1

由于您已经建立了关联,因此您应该能够执行以下操作:

f = Person.joins(:events)
f = f.where(:events => { :type => "the_type_you_are_searching_for" })
f = f.group('people.id')
f = f.select('people.*, max(events.date) as last_event_date')
people = f.all # though you probably want to paginate really

我已经逐行完成了,以便在这里更容易阅读,但通常你会看到where,groupselect在同一行上一个接一个地链接在一起。

你需要,group否则如果他们参加过多个活动,你会让人们多次返回。

习惯selectlast_event_date在结果中包含 。

于 2013-07-17T16:15:01.290 回答
0

为什么不直接编写自定义 SQL 查询?它看起来像这样:

SELECT * FROM person_events 
INNER JOIN people ON people.id = person_events.person_id
INNER JOIN events ON events.id = person_events.event_id AND events.type = 'EventType'
于 2013-07-17T16:06:54.593 回答