简体   繁体   English

如何通过记录获取具有确切指定的has_many的记录?

[英]How to fetch records with exactly specified has_many through records?

I feel like I have read all SO "has_many through" questions but none helped me with my problem. 我觉得我已经阅读了所有的“ has_many through”问题,但是没有一个问题可以帮助我。

So I have a standard has_many through setup like this: 所以我通过这样的设置有一个标准的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, What I want is pretty simple: IMO,我要的很简单:

Find all users that have a product association to products A, B, and C, no more, no less 查找与产品A,B和C具有产品关联的所有用户

So I have a couple of products and want to find all users that are connected to exactly those products (they shouldn't have any other product associations to other products). 因此,我有几个产品,并且想找到与这些产品完全相关的所有用户(他们不应与其他产品建立任何其他产品关联)。

This is the best I came up with: 这是我想出的最好的方法:

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}")

It doesn't work though, it also returns users connected to more products. 但是,它不起作用,它还会使用户连接到更多产品。

I also toyed around with merging scopes but didn't get any result. 我还开玩笑合并范围,但没有得到任何结果。

All hints appreciated! 所有提示表示赞赏! :) :)

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

It does two things, find users with: 1) all the product associations and 2) no other product associations. 它有两件事,找到具有以下条件的用户:1)所有产品关联,以及2)没有其他产品关联。

Sqlfiddle example: http://sqlfiddle.com/#!2/aee8e/5 Sqlfiddle示例: http ://sqlfiddle.com/#!2/aee8e/5

It can be Railsified™ (somewhat) in to: 可以通过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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM