2017-04-09 9 views
1

例として、これらの3つのテーブルがあるとします。 イベント、出席(テーブルの結合)、およびユーザー。すべての関連付けが含まれる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.by_attendended_users(user_4, user_9)を言うと Events: [1, 2]

を取得したい

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

私はjoins(:attendances).where("attendances.user_id IN :user_ids")または類似した何かの線に沿って何かを考えていたが、必要に応じて、非常にそれが動作するように持っていませんまだ。どんな助けやフィードバックも大歓迎です!

EDIT:@AbMが指摘しているように、は2人のユーザーが一度に参加する場合、ユーザーを見つけるために使用できるちょっとしたハックがあります。クエリの2番目の部分が最初の部分を上書きしているため、このソリューションは機能しません。

最低限の要件は唯一、それは(今のところ)2を使用する必要があることを述べているが、理想的には、これは、組合の任意の数の上で動作することができるはず

また、私のことができるようにしたいのですがこれをスコープとして使用すると、他のスコープと連鎖してさらにフィルタリングすることができます。 @AbMによる解決策は、そのスコープが他のフィルタのチェーンで最初に呼び出された場合にのみ、これで動作します。

+0

@AbM - 非常に賢いです!最適なのは、2人以上のユーザーを使用する状況を考慮したいと思いますが、それは現在最低限必要な要件なので、これ以上の解決策がない場合は、これを喜んで使用します。 :) ありがとうございました! – Rockster160

+0

それは動作していないようです。私は 'どこ(出席者:{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

これは、1人のユーザーが複数の出席者を同じイベントに出席させることはできません。検索結果がカウントによって混乱することがありますが、それは良いスタートです。 – Rockster160

+0

あなたは何を意味するのかよく分かりません。なぜ、1人のユーザーが同じイベントに複数の出席者を持っていますか? – AbM

関連する問題