2009-03-31 6 views
3

私はモデルがあります:ユーザーとアイテム、それらの間の多対多関係。定義された属性を持つ商品(正確にはもう商品がない)を取得する方法、つまり色が[赤]、[黒]のアイテムを持つユーザー。Railsでhas_manyを逆転しました

はもちろん、私はこのような何か行うことができます。

User.all :joins => [:items, :items], :conditions => {:"items.color" => "red", :"items_users.color" => 'black'} 

をしかし、より多くの属性のために非常に面倒なことになるだろう。

User.all(:conditions => ["items.color in (?), ['red', 'black']], :include => :items) 

をしかし、この1だから、唯一の解決策はある色= [「など」、「赤」「黒」、「青」]

を持つアイテムでも、ユーザーを返します。 は私も行うことができますすべてを取得し、ルビ構文でソートするには? 1つのSQLクエリまたはRails AR構文でそれを行う方法は?

答えて

1

私の意見では、プログラマの時間や読みやすさを最適化方法:

#get all users who have items which are both red and black but no other colors 
candidate_users = User.all(:include => :items) 
candidate_users.reject! do |candidate| 
    candidate.items.map {|item| item.color}.sort != ['black', 'red'] 
end 

あなたがそこにユーザーのメトリックトラック輸送をループすることが期待されている場合は、それをSQLする必要があります。警告:SQLは私のバッグではありません、赤ちゃん:使用する前にテストしてください。私は邪悪な混乱はないと思い何

select users.*, items.* FROM users 
    INNER JOIN items_users ON (items_users.user_id = users.id) 
    INNER JOIN items ON (items_users.item_id = items.id) 
    GROUP BY users.id HAVING COUNT(DISTINCT items.color) = 2 

1)すべてのユーザー/項目の組み合わせ 2をグラブ)「あなたを意味し、正確に2つの異なる色

のアイテムを持っているユーザーにダウンWinnows必要でしょう:

candidate_users.reject! do |candidate| 
    candidate.items.map {|item| item.color}.sort != ['black', 'red'] 
end 

あなたはおそらく完全にここでルビーの必要性を排除することができますが、SQLは醜いの7つの味を取得する予定です。 (Cross join、oh my ...)

+0

シンプルですが、これはレールの規則を破り、チェーンでの遅延読み込みを防止します(これは 'lambda' –

関連する問題