我觉得我已经阅读了所有SO" has_many通过"问题,但没有一个帮助我解决我的问题。
所以我通过这样的设置有一个标准的has_many:
class User < ActiveRecord::Base
has_many :product_associations
has_many :products, through: :product_associations
end
class ProductAssociation < ActiveRecord::Base
belongs_to :user
belongs_to :product
end
class Product < ActiveRecord::Base
has_many :product_associations
has_many :users, through: :product_associations
end
IMO,我想要的很简单:
查找与产品A,B和C具有产品关联的所有用户,不多也不少
所以我有几个产品,并希望找到所有与完全这些产品相关的用户(他们不应该与其他产品有任何其他产品关联)。
这是我提出的最好的:
products # the array of products that I want to find all connected users for
User
.joins(:product_associations)
.where(product_associations: { product_id: products.map(&:id) })
.group('products.id')
.having("COUNT(product_associations.id) = #{products.count}")
虽然它不起作用,但它也会返回与更多产品相关的用户。
我还玩弄merging scopes,但没有得到任何结果。
所有提示都表示赞赏! :)
答案 0 :(得分:1)
select * from users
join product_associations on product_associations.user_id = users.id
where product_associations.product_id in (2,3)
and not exists (
select *
from product_associations AS pa
where pa.user_id = users.id
and pa.product_id not in (2,3)
)
group by product_associations.user_id
having count(product_associations.product_id) = 2
它做了两件事,找到用户:1)所有产品关联和2)没有其他产品关联。
Sqlfiddle示例:http://sqlfiddle.com/#!2/aee8e/5
它可以是Railsified™(有点)到:
User.joins(:product_associations)
.where(product_associations: { product_id: products })
.where("not exists (select *
from product_associations AS pa
where pa.user_id = users.id
and pa.product_id not in (?)
)", products.pluck(:id))
.group('product_associations.user_id')
.having('count(product_associations.product_id) = ?', products.count)