1

B からの一致するすべてのレコードが条件を満たす A からのレコードを返そうとしています。現時点で、私のクエリは A からのレコードを返しますが、条件を満たしている B からのレコードがあります。これを現実世界のシナリオに当てはめてみましょう。

Post.joins(:categories)
    .where(:categories => { :type => "foo" })

これは、タイプ「foo」のカテゴリを持つ s を返しPostます。私が欲しいのはPost、カテゴリがすべてタイプ「foo」の s です!

助けてください!

4

3 に答える 3

2

IRC の #rubyonrails に投稿されている db/schema.rb を次のように使用します。

Incident.select("incidents.id").
joins("INNER JOIN category_incidents ON category_incidents.incident_id = incidents.id").
joins("INNER JOIN category_marks ON category_marks.category_id = category_incidents.category_id").
where(:category_marks => { :user_group_id => current_user.user_group_id }).
group("incidents.id").
having("SUM(CASE WHEN category_marks.inc = 1 THEN 1 ELSE 0 END) = count(category_indicents.incident_id)")

トリックを行うでしょう。

current_user の category_marks を結合し、.inc = 1 のレコードの数が結合されたすべてのレコードの数と等しいかどうかを確認します。

これはincident.idのみをフェッチすることに注意してください

于 2013-03-15T13:09:31.753 に答える
1

このクエリの最後に select を追加して、すべてのカテゴリのタイプが foo かどうかを確認します。また、Category モデルにインスタンス メソッドを追加することで、そのチェックを簡素化します。

Post.joins(:categories).select{|p| p.categories.all?(&:type_foo?)}

カテゴリ モデル

 def type_foo?
   type == "foo"
 end

追加:これは少し「ハック」ですが、この方法でスコープにすることができます。

class Post < ActiveRecord::Base
  scope :category_type_foo, lambda{ 
    post_ids = Post.all.collect{|p| p.id if p.categories.all?(&:type_foo?).compact
    Post.where(id: post_ids) }
end
于 2013-03-15T12:10:34.370 に答える
0

反対方向にクエリを試しましたか? すなわち

Categories.where(type: 'foo').joins(:posts)

私はあなたの質問を誤解したかもしれません。

別の選択肢は

Post.joins(:classifications).where(type: 'foo')
于 2013-03-15T12:30:26.033 に答える