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

时间:2014-03-18 19:42:27

标签: ruby-on-rails ruby-on-rails-3 activerecord has-many-through

我觉得我已经阅读了所有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,但没有得到任何结果。

所有提示都表示赞赏! :)

1 个答案:

答案 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)