Rails 5.1:渴望在多态关联中加载子记录

时间:2018-07-16 18:28:18

标签: ruby-on-rails ruby polymorphism eager-loading awesome-nested-set

我有一个非常复杂的关联,我使用awesone_nested_set gem来管理Ratecard::RuleIndex的父母和孩子:

class Inventory::Inventory < ApplicationRecord
  has_many :ratecards_rules, class_name: 'Ratecard::RatecardsRule', through: :ratecards
  has_many :rule_indices, class_name: 'Ratecard::RuleIndex', through: :ratecards do
    def children
      Ratecard::RuleIndex.each_with_level(Ratecard::RuleIndex.root.children) do |index, level|
        puts index.index_value
      end
    end
  end
end

class Ratecard::Ratecard < ApplicationRecord
  has_many :ratecards_rules, class_name: 'Ratecard::RatecardsRule'
  has_many :rule_indices, class_name: 'Ratecard::RuleIndex', 
            through: :ratecards_rules, source: :rulable, 
            source_type: 'Ratecard::RuleIndex'
end

class Ratecard::RatecardsRule < ApplicationRecord
  belongs_to :rulable, polymorphic: true, optional: true
end

class Ratecard::Rule < ApplicationRecord
  has_many :ratecards_rules, class_name: 'Ratecard::RatecardsRule', as: :rulable
  has_many :ratecards, class_name: 'Ratecard::Ratecard', through: :ratecards_rules
end

class Ratecard::RuleIndex < Ratecard::Rule
  has_many :ratecards_rules, class_name: 'Ratecard::RatecardsRule', as: :rulable
  has_many :ratecards, class_name: 'Ratecard::Ratecard', through: :ratecards_rules
end

在控制台中,我可以这样做:

i=Inventory::Inventory.where(id: [200,201,202]).includes(:ratecards)
                      .where(ratecard_ratecards: {id: 1}).preload(:rule_indices)

会预加载Ratecard::RuleIndex个父记录(索引)。但是我需要以某种方式预加载子记录。在我这样做的那一刻

i.collect{|x| {indices: x.rule_indices.children.collect{|i| {id: i.index_value}} }}

我得到了想要的输出,但是执行了额外的查询,看起来像他的:

Ratecard::RuleIndex Load (0.8ms)  SELECT  "ratecard_rules".* FROM "ratecard_rules" WHERE "ratecard_rules"."type" IN ('Ratecard::RuleIndex') AND "ratecard_rules"."parent_id" IS NULL ORDER BY "ratecard_rules"."lft" ASC LIMIT $1  [["LIMIT", 1]]
Ratecard::Rule Load (0.5ms)  SELECT "ratecard_rules".* FROM "ratecard_rules" WHERE "ratecard_rules"."parent_id" = $1 ORDER BY "ratecard_rules"."lft" ASC  [["parent_id", 60]]
0.95
=> [{:indices=>[{:id=>0.95e0}]}]

是否有某种方式可以预加载(由于多态关联,并且特别需要“预加载”)我的孩子记录,所以以后不会再收到N + 1个查询? 我很高兴得到任何提示。谢谢。

到目前为止,我一直在尝试实现has_many associaion extension,但是由于无法使子记录预先加载,因此无法达到预期的效果。 我了解这是由于我的查询转到了Ratecard :: RatecardsRule,在这里,我的“父”索引记录由rulable_typerulable_id抓取。如果我能以某种方式预加载子记录(与父母一起存储在“ ratecard_rules”表中并由Awesome Nested Set gem管理),那就太好了。

0 个答案:

没有答案