2017-04-09 114 views
1

作爲一個例子,假設我有這三個表: 事件,出勤(加入表)和用戶。ActiveRecord查詢所有關聯包括

Event has_many attendances and has_many users through attendances 
User has_many attendances and has_many events through attendances 
Attendance belongs_to attendance and belongs_to user 

我希望能夠查詢所有事件以查找x個用戶都參加了哪裏。 作爲一個例子:

Event  | Users who attended Event 
1    [1, 3, 4, 6, 9] 
2    [1, 4, 9] 
3    [3, 4, 6] 
4    [2, 3, 6] 

我想說 Event.by_attendended_users(user_4, user_9)並獲得 Events: [1, 2]

我想沿着joins(:attendances).where("attendances.user_id IN :user_ids")或類似的東西線的東西,但還沒有完全得到它的工作根據需要然而。任何幫助或反饋非常感謝!

編輯:作爲一些額外的細節,正如@AbM指出的,如果加入一次只有2個用戶,有一點可以用來查找用戶的黑客。解決方案不起作用,因爲查詢的第二部分覆蓋了第一部分。

理想情況下,應該能夠在任意數量的協會工作,但最起碼​​的要求,只是說,它需要使用2(現在)

此外,我希望能夠使用這個作爲範圍,這意味着它可以鏈接到其他範圍進一步過濾。 @AbM的解決方案只有在其他過濾器的鏈中首先調用該範圍時才能使用該解決方案。

+0

@AbM - 非常聰明!理想情況下,我想解釋一個使用超過2個用戶的情況,但這僅僅是最低要求,所以如果沒有更好的解決方案,我會很樂意使用這個。 :) 謝謝! – Rockster160

+0

這似乎沒有工作。我認爲'where(參加者:{user_id:user_9.id})'覆蓋了初始範圍並且重新回到原始問題。 :( – Rockster160

回答

0
user_ids = [1, 3, 5] 
events = Event.joins(:attendances) 
user_ids.each {|user_id| events = events.where('attendances.user_id = ?', user_id) } 

# events now contains all events where all specified users attended 
1
user_ids = [4, 9] 
events = Event 
user_ids {|user_id| events = events.where(id: Event.joins(:attendances).where(attendances: {user_id: user_id})) } 
events 

你可以做的另一種方法是使用自定義計算:

user_ids = [4, 9] 
Event.joins(:attendances).having('COUNT(CASE WHEN attendances.user_id IN (?) THEN 1 END) = ?', user_ids, user_ids.length).group(:id) 
+0

這不允許一個用戶多次出席同一個事件,因爲搜索結果會被計數混淆,但這是一個很好的開始,我可以使用常規數組操作手動完成其餘部分。 – Rockster160

+0

我不太清楚你的意思,爲什麼一個用戶會有多次參加同一個活動? – AbM