简体   繁体   中英

Rails - eager loading with has_many_through association

I have a very simple has_many_through association as follows:

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

In the index of my retailers controller, I want to display a list of all the retailers with their associated tags. If I just have in my controller @retailers = Retailer.all and then loop over all the retailers in my view, I have a N+1 queries problem.

I can solve this issue using Postgresql directly and it works fine, but I would like to understand how to do it in Rails.

When I do @retailers = Retailer.eager_load(retailer_tags: :tag).all (or any of includes / preload / joins), I still get N+1 queries.

What am I doing wrong? Thanks for you help

Do @retailers = Retailer.eager_load(:tags).all OR you can do:

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

Using includes allows rails to make the most efficient query depending on the situation. This will act as eager_load unless the LEFT_OUTER_JOIN would return an error at which point Rails will do it in 2 queries like preload

@retailers = Retailer.includes(:tag)

There are three methods in rails by using them you can eager load the associations,

  • includes
  • preload
  • eager_load

Examples for your case

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

For more details please see http://blog.arkency.com/2013/12/rails4-preloading/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM