【问题标题】:Rails: query the existence of a join table's childRails:查询连接表的孩子是否存在
【发布时间】:2015-09-07 01:14:51
【问题描述】:

设置:

class User < ActiveRecord::Base
  has_many :sales
  has_many :sold_items, through: :sales, source: item
  has_many :returns, through: sold_items
end

class Sale < ActiveRecord::Base
  belongs_to :user
  belongs_to :item
  has_one :return
end

class Item < ActiveRecord::Base
  has_many :sales
  has_many :returned_sales, through: :sales, source: :return
end

class Return < ActiveRecord::Base
  belongs_to :sale
end

问题:

编辑:澄清问题。我希望给定用户不返回所有项目。

提示:项目可能有销售范围为用户:如果一个项目有两个销售,一个返回一个不返回,我不想显示该项目。

user_items = user.sold_items.distinct
goal = user_items.reject {|i| i.returned_sales.first}

这不起作用,因为它查询所有returned_sales 的商品,而不仅仅是用户范围内的商品。


编辑:添加返回关联has_one :returned_item, through: :sale, source: :item并查询

returned_items = user.returns.map {|r| r.item}
goal = user_items - returned_items

成功但不性感:首选单个查询。

【问题讨论】:

  • 您想要一个左反连接,即查找所有已售商品,执行左连接以查找该用户返回的商品,并在 where 子句中仅保留右侧为空的行.另一种选择是将NOT EXISTS 与子查询一起使用。我不会说 Rails/ActiveRecord,所以我不能把它从 SQL 翻译成 Rails 语言,但希望这能让你走上正轨。
  • @CraigRinger 谢谢,我正在寻找用户未退回的商品,而不是未退回的销售(请查看我的编辑)

标签: sql ruby-on-rails postgresql activerecord rails-activerecord


【解决方案1】:

特价:

def self.not_returned
  where.not(Return.where("returns.sale_id = sales.id").exists)
end

那么你可以:

Sale.not_returned

【讨论】:

  • 也许我的问题措辞不当。我想要给定用户未返回的所有项目。 (商品可能有很多针对用户的销售:如果一个商品有两个销售,一个退货,一个不退货,我不想显示该商品。)
  • 因此,给定一个 User 实例,显示该用户购买的所有商品,而该用户从未在任何用户的销售中退回该商品?
猜你喜欢
  • 2017-03-14
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 2017-05-31
  • 2011-11-25
  • 2016-09-20
  • 2010-12-06
相关资源
最近更新 更多