【问题标题】:How to fetch records with exactly specified has_many through records?如何通过记录获取具有精确指定has_many的记录?
【发布时间】:2014-03-18 19:42:26
【问题描述】:

我觉得我已经阅读了所有“通过”的问题,但没有一个对我的问题有帮助。

所以我有一个标准的 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,但没有得到任何结果。

感谢所有提示! :)

【问题讨论】:

  • 您的架构似乎完全不正确——所以一个订单只能有一个产品?
  • 这只是一个人为的例子。我更新了课程,希望现在更清楚了。

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


【解决方案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)

【讨论】:

  • 不,has_and_belongs_to_many 与 has_many 不同。
  • 为了记录(双关语),has_and_belongs_to_many 与引擎盖下的has_many through 几乎相同。
  • sigh 我会忽略那些刻薄的“假代码”言论,好吗?您的代码不起作用,仍然返回具有两个以上产品的用户。
  • 抱歉,如果我听起来很尖刻,漫长的一天 :)。我已经更新了代码,我相信它现在可以工作了。
  • 不用担心。您的代码现在可以工作了! :) 结果比我预期的要复杂...
猜你喜欢
  • 1970-01-01
  • 2016-09-24
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
相关资源
最近更新 更多