Как избежать N + 1 запросов с will_paginate? - PullRequest
3 голосов
/ 09 февраля 2012

Мое приложение замедляется из-за N + 1 запросов.Я использую гем will_paginate с Rails 3.1 и Oracle 11.2.

Обычно решение состоит в том, чтобы использовать ActiveRecord # includes () для чтения дочерних записей одновременно с извлечением родительских записей, нокаждая попытка, которую я сделал, кажется, либо не работает с will_paginate, либо заканчивается загрузкой всей базы данных в память.Я попытался создать именованную область, но кажется, что области выбираются сразу при вызове, а не лениво.

class Parent < ActiveRecord::Base
  has_many :children, :dependent => :delete_all
end

class Child < ActiveRecord::Base
  belongs_to :parent
end

class ParentsController < ApplicationController
def index
  @parents = Parent.paginate page: params[:page], order: 'id', per_page: 32
end

Index.html.erb содержит, среди прочего,

<%= page_entries_info @parents %>
<%= will_paginate @parents, :container => false %>
<% @parents.each do |parent| %>
<%= parent.call_to_method_that_uses_children_association_causing_N+1_query %>
<% end %>

ЕслиЯ не могу позволить себе извлечь всю базу данных в память, и не хочу получать страницу родителей, за которой следует N дочерних выборок, есть ли другие варианты, кроме отказа от will_paginate?

Кроме того, есть ли какие-либосодержательная документация для will_paginate?Информация о github довольно скудная.Например, что означает опция: container для метода will_paginate?

1 Ответ

7 голосов
/ 09 февраля 2012
Parent.includes(:children).paginate(:page => params[:page], :per_page => 30)

Из другого вопроса, который похож на ваш

...