将相同的 arel 子句链应用于不同的关系

Apply the same chain of arel clauses to different relations

我有两个 ActiveRecord 关系,称它们为 rel1rel2。他们每个人都添加了各种不同的 joinswhere 子句。

我想对它们中的每一个应用相同的子句序列,我不想重复自己。

一种方法是创建一个函数:

def without_orders rel
   rel.joins("LEFT JOIN orders ON customers.id = orders.customer_id").where("customers.id IS NULL")
end

rel1 = Customer
rel2 = Customer

# add a bunch of clauses to rel1
# add some other clauses to rel2

rel1 = without_orders(rel1)
rel2 = without_orders(rel2)

理想情况下,我不会将 without_orders 作为一个单独的函数。我会以某种方式将 joinswhere 放在 func 的本地内容中,并将该内容应用于 rel1rel2

这可能吗?如果不是,这里正确的方法是什么?

您可以将它们全部放入单独的范围中:

scope :without_orders, -> { joins("LEFT JOIN orders ON customers.id = orders.customer_id").where(customers: { id: nil }) }

然后您可以将它与其他作用域链接起来。

Customer.without_orders.where(foo: bar)

这是积极支持关注的一个很好的候选者

# app/models/concerns/customer_related.rb

module CustomerRelated

  extend ActiveSupport::Concern

  module ClassMethods

    def whithout_orders
      joins("LEFT JOIN orders ON customers.id = orders.customer_id").where("customers.id IS NULL")
    end

  end

end

然后在您的模型中包含它:

include CustomerRelated

然后您可以在任何包含问题的模型上像范围一样使用它

Rel1.without_orders

Rel2.without_orders