2016-05-26 3 views
0

У меня есть очень простой has_many_through ассоциации следующим образом:Rails - жадная загрузка с 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 (или любой из включений/preload/join), я все равно получаю N + 1 запросов.

Что я делаю неправильно? Спасибо вам помочь

ответ

3

ли @retailers = Retailer.eager_load(:tags).all или вы можете сделать:

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

Использование включает позволяет рельсы, чтобы сделать наиболее эффективный запрос в зависимости от ситуации. Это будет действовать как eager_load если LEFT_OUTER_JOIN не будет возвращать ошибку, при которой точке Rails будет делать это в 2-х запросах, как preload

+1

Работал отлично, спасибо, за исключением того, я должен был сделать: @retailers = Retailer.eager_load (: метки) .all – Alexandre

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/

Смежные вопросы