3

モデルがあるとしましょう: User と Item およびそれらの間の多対多の関係。定義された属性を持つ正確に (それ以上) アイテムを持っていないユーザー、つまり、色 = ['red', 'black'] のアイテムを持っているユーザーを取得する方法。

もちろん、私はこのようなことをすることができます:

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

しかし、より多くの属性については、かなり面倒です。私もできる:

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

しかし、これは、色 = ['red', 'black', 'blue', 'etc'] を持つアイテムを持つユーザーも返します

だから、唯一の解決策は、すべてを取得し、ルビ構文でソートすることですか? 1 つの SQL クエリまたは Rails AR 構文でそれを行う方法は?

4

1 に答える 1

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つの異なる色のアイテムを持っているユーザーにウィノウダウンします

つまり、次のことを行う必要があります。

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

ここではおそらくルビーの必要性を完全に排除することができますが、SQLは7種類の醜いものを取得する予定です。(クロス結合、オーマイ...)

于 2009-03-31T08:02:36.280 に答える