2013-07-17 35 views
0

我有一些活動,人。他們之間有多對多的關係,所以有一個PersonEvent將Events與People連接起來。請幫我想一想Ruby on Rails中更好的算法

事件有一個日期,然後鍵入

PersonEvent有事項標識和爲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. 

任何人都可以推薦一個更好的算法嗎?

回答

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否則,如果他們參加過多個活動,您會多次返回人員。

自定義select是在結果中包含last_event_date

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' 
3

在回報率,這將是:

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

Rails的joins將創建一個INNER JOIN,這將拋棄誰沒有符合相關的事件的人標準where

你不解釋你如何保留考勤信息的日期,所以我會留給你。

相關問題