如何使用自定义eagerload方法?

时间:2015-07-07 10:54:15

标签: ruby-on-rails ruby-on-rails-4 activerecord

我有以下一行

Shipment.find_shipments(company_id: current_company.id).includes(:customer, :recipient, :carrier_product, ...)

货件属于carrier_product

问题是,在CarrierProduct模型上,它具有自引用关联,即每个产品可以存储其拥有产品的carrier_product_id。这个链可以是多个链接长

然后我创建了以下方法来获取所有祖先

def find_top_level_ancestors_from_ids(carrier_product_ids: [])
      self.where('carrier_products.id IN
                  (WITH RECURSIVE tree(id, parent_id) AS (
                     SELECT cp.id, cp.carrier_product_id FROM carrier_products cp
                     WHERE cp.id IN (?)
                   UNION ALL
                     SELECT cp.id, cp.carrier_product_id FROM carrier_products cp JOIN tree ON cp.id = tree.parent_id)
                    SELECT id FROM tree)', carrier_product_ids)
    end

我想在.includes(:carrier_prouct)中使用此方法的结果,而不是默认值,它只加载第一级父级。

这可能吗?

由于

1 个答案:

答案 0 :(得分:0)

你应该考虑制作一个班级功能。然后可以根据需要将其链接起来。

def self.find_top_level_ancestors_from_ids(carrier_product_ids: [])
  joins(:carrier_product).where('carrier_products.id IN
    (WITH RECURSIVE tree(id, parent_id) AS (
          SELECT cp.id, cp.carrier_product_id FROM carrier_products cp
          WHERE cp.id IN (?)
          UNION ALL
          SELECT cp.id, cp.carrier_product_id FROM carrier_products cp JOIN tree ON cp.id = tree.parent_id)
          SELECT id FROM tree)', carrier_product_ids)
end

注意 self.制作类级方法。

这应该允许你这样做:

Shipment.find_shipments(company_id: current_company.id)
        .includes(:customer, :recipient, ...)
        .find_top_level_ancestors_from_ids(carrier_product_ids: [1,2,3,...])