【问题标题】:Why isn't this second-level eager loading working?为什么这个二级急切加载不起作用?
【发布时间】:2015-05-28 20:38:28
【问题描述】:

我有三个模型,Subrating、Thing 和 Category。子分类belongs_to Thing 和Thing has_many Categories。

我有一个 Subratings 列表,我正在尝试快速加载与每个 Subratings 关联的事物相关联的类别。

这是我尝试过的:


控制器

@subratings = Subrating.all( :include => { :thing => :categories })

查看

<% @subratings.sort_by(&:rating).reverse.each do |subrating| %>
  <%= subrating.thing.categories.sort_by(&:thing_count).second.name %>
<% end %>

但这并不能解决我的 n+1 问题。我什至不确定数据库是延迟加载事物还是类别或两者兼而有之,但这是在我的服务器中不断重复出现数百次的行:

CACHE (0.0ms)  SELECT COUNT(*) FROM "things" INNER JOIN "category_things" ON "things"."id" = "category_things"."thing_id" WHERE "category_things"."category_id" = $1  [["category_id", 1]]

我做错了什么?


关联

class Subrating < ActiveRecord::Base
  belongs_to :thing
end

class Thing < ActiveRecord::Base
  has_many :category_things
  has_many :categories, :through => :category_things
  has_many :subratings
end

class Category < ActiveRecord::Base
  has_many :category_things
  has_many :things, :through => :category_things
end

class CategoryThing < ActiveRecord::Base
  belongs_to :category
  belongs_to :thing
end

【问题讨论】:

    标签: mysql ruby-on-rails ruby database associations


    【解决方案1】:

    也许您应该尝试在 Model 类中调用包含,例如:

    @subratings = Subrating.includes(thing: [:categories])
    

    如 http://apidock.com/rails/ActiveRecord/QueryMethods/includes 中所述

    虽然它也应该按照您尝试的方式工作,因为 .all 是 .find(:all) 的别名,但我建议尝试一下:

    @subratings = Subrating.all( :includes => { :thing => [:categories] })
    

    (请注意,我将 include 更改为 includes 并将事物指向一个数组)

    【讨论】:

    • 这两个查询都会导致相同的 N+1 问题。我只是不断地重复同一条线,数百次。
    • 没关系,问题来自“.sort_by(&:thing_count)”。
    【解决方案2】:
    @subratings = Subrating.includes(:thing => :categories)
    

    这也适用于您,并为您提供子字符串表的所有记录。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      相关资源
      最近更新 更多