在 Rails 6 中,如何向左外连接查找器添加条件?

In Rails 6, how do I add a condition to a left-outer-joins finder?

我正在使用 Rails 6.1.4.4。我有这个模型 has_many

class MyObject < ApplicationRecord

    has_many :products, inverse_of: :application, as: :item

如何编写执行左外连接并在 LEFT-OUTER-JOIN-ON 子句中添加条件的作用域?我已经退回到原始 sql …

scope :awaiting_funding, ->(resubmissions: false) {

  joins("LEFT OUTER JOIN products on products.item_id = my_objects.id and products.product_type = 11 and products.item_type = ‘MyObject’”).where('products.id is null')

}

但我想将其转换为更 Rails 的查找器方法。

这个有用吗?

scope :awaiting_funding, ->(resubmissions: false) {
  left_outer_joins(:products).where(product_type: 11, item_type: 'MyObject', products: { id: nil })
}

定义一个新的has_many

class MyObject < ApplicationRecord

    has_many :products, inverse_of: :application, as: :item
    has_many :my_object_products, -> { where(product_type: 11, item_type: 'MyObject') }, class_name: 'Product'

现在您可以定义范围

scope :awaiting_funding, ->(resubmissions: false) {
   where.missing(:my_object_products)
}

这将创建查询,其中 product_typeitem_type 是 LEFT OUTER JOIN

中 ON 的一部分

PS:为 my_object_products 使用更好的名称,但你明白了。

我会给你一个更通用的例子 Left Outer Join

Source.
 select('a.*', 'count(b.*)').
 left_outer_joins(:b).
 joins(:c).
 where('c.body_parser = ?', true).
 group('a.id').
 having('count(b.id) = 0').
 all

否则,您也可以使用includes。这将生成一个 LEFT OUTER JOIN 查询

MyObject.includes(:products).where(product_type: 11, item_type: 'MyObject', products: { id: nil })