Rails - 渴望通过has_many_through关联加载

时间:2016-05-26 12:55:14

标签: ruby-on-rails rails-activerecord

我有一个非常简单的has_many_through关联如下:

class Retailer < ActiveRecord::Base
  has_many :retailer_tags
  has_many :tags, through: :retailer_tags
end

class Tag < ActiveRecord::Base
  has_many :retailer_tags
  has_many :retailers, through: :retailer_tags
end

class RetailerTag < ActiveRecord::Base
  belongs_to :retailer
  belongs_to :tag
end

在我的零售商控制器的索引中,我想显示所有零售商及其相关标签的列表。如果我只是在我的控制器@retailers = Retailer.all中,然后在我的视图中遍历所有零售商,那么我有一个N + 1查询问题。

我可以直接使用Postgresql解决这个问题并且它工作正常,但我想了解如何在Rails中完成它。

当我@retailers = Retailer.eager_load(retailer_tags: :tag).all(或任何包含/预加载/加入)时,我仍然会收到N + 1个查询。

我做错了什么? 谢谢你的帮助

3 个答案:

答案 0 :(得分:3)

执行@retailers = Retailer.eager_load(:tags).all或者你可以这样做:

@retailers = Retailer.includes(:tag).all

使用includes允许rails根据情况进行最有效的查询。这将充当eager_load,除非LEFT_OUTER_JOIN将返回错误,此时Rails会在preload

等2个查询中执行此操作

答案 1 :(得分:0)

@retailers = Retailer.includes(:tag)

答案 2 :(得分:0)

使用它们有三种方法,你可以急切加载关联,

  • 包括
  • 预加载
  • eager_load

案例

retaillers = Retailer.includes(:tag).all
retaillers = Retailer.preload(:tag).all
retaillers = Retailer.eager_load(:tag).all

有关详细信息,请参阅http://blog.arkency.com/2013/12/rails4-preloading/