如何避免使用will_paginate进行N + 1查询?(How to avoid N+1 queries with will_paginate?)

我的应用由于N + 1个查询而变慢。 我在Rails 3.1和Oracle 11.2中使用了will_paginate gem。

通常,解决方案是使用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上的信息非常稀少。 例如,will_paginate方法的container选项是什么意思?

My app is slowed down by N+1 queries. I'm using the will_paginate gem with Rails 3.1 and Oracle 11.2.

Normally, the solution would be to use ActiveRecord#includes() to read in child records at the same time that I fetch the parent records, but every attempt I've made seems to either not work with will_paginate, or end up fetching the whole database into memory. I tried making a named scope, but it seems scopes are fetched immediately when called, not lazily.

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 contains, among other things,

<%= 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 %>

If I can't afford to fetch the whole database into memory, and don't want to fetch a page of parents, followed by N child fetches, are there other options besides abandoning will_paginate?

Also, is there any substantial documentation for will_paginate? The info on github is pretty sparse. For example, what does the :container option to will_paginate method mean?

最满意答案

Parent.includes(:children).paginate(:page => params[:page], :per_page => 30)

从另一个类似于你的问题

Parent.includes(:children).paginate(:page => params[:page], :per_page => 30)

From another question that is similar to yours

更多推荐