问题:在 Rails 5 中,如何返回两个作用域的并集或将它们合二为一?

我正在努力要么返回两个范围的联合,要么在我的 Rails 应用程序中将它们合并为一个。我正在寻找的结果是检索满足以下任一范围的所有订单:Order.with_buyer_like 或 Order.with_customer_like。那就是我正在寻找集合的并集。重要的是,我需要将这些作为 ActiveRecord::Relation 而不是数组返回。否则,我只会做

results =  Order.with_buyer_like + Order.with_customer_like

我也尝试使用“或”运算符,但出现错误:

Order.with_seller_like('pete').or(Order.with_customer_like('pete'))
ArgumentError: Relation passed to #or must be structurally compatible. Incompatible values: [:joins]

我也尝试过将这些范围合并为一个,但我不能完全让它工作。

这是我的设置:

class Company
  has_many :stores
end 

class Store
  belongs_to :company
end

class Order
  belongs_to :buying_store, class_name: 'Store', foreign_key: 'buying_store_id', required: true 
  belongs_to :selling_store, class_name: 'Store', foreign_key: 'selling_store_id', required: true

  scope :with_buyer_like, ->(search_term) { joins(buying_store: [:company], :customer).where(['stores.name LIKE ? OR companies.name LIKE ?', "%#{search_term.gsub(/ /, '_').downcase}%", "%#{search_term.gsub(/ /, '_').downcase}%"]) }

  scope :with_customer_like, ->(search_term) { joins(:customer).where(['first_name LIKE ? OR last_name LIKE ? OR mobile_number LIKE ? OR email LIKE ?', "%#{search_term.gsub(/ /, '_').downcase}%", "%#{search_term.gsub(/ /, '_').downcase}%", "%#{search_term.gsub(/ /, '_').downcase}%", "%#{search_term.gsub(/ /, '_').downcase}%"] ) } 
end

解答

这个博客很好地解释了您面临的问题。

在这里总结一下,您必须确保joinsincludesselect(简称为要获取的 AR 数据的结构)在两个范围之间是一致的。

只要您确保两个范围具有相同的连接,这种语法就是要走的路。

Order.with_seller_like('pete').or(Order.with_customer_like('pete'))

要迈出第一步,请检查这是否有效(但不推荐):

Order.where(id: Order.with_seller_like('pete')).or(Order.where(id: Order.with_customer_like('pete')))

如果您要在输出中查找 onlyOrder数据,我建议不要使用joins并使用查询的子查询样式。

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐