Rails:在调用page_entries_info

时间:2016-01-23 08:31:28

标签: ruby-on-rails-3 ruby-on-rails-3.2 rubygems will-paginate

我的应用程序使用rails'3.2.20',mysql2'0.3.20'和will_paginate'3.0.7'

我正在尝试加载用户记录

@users = User.paginate(:page => params[:page], :per_page => 20)

在控制台

中执行的查询
User Load (0.3ms)  SELECT `users`.* FROM `users` LIMIT 20 OFFSET 0
(0.3ms)  SELECT COUNT(*) FROM `users` 

通常,will_paginate会对集合运行两个查询并计算

但是在视图

中使用page_entries_info时,我又得到了一个额外的查询
User Load (0.3ms)  SELECT `users`.* FROM `users` LIMIT 20 OFFSET 0
(0.3ms)  SELECT COUNT(*) FROM `users` 
User Load (0.2ms)  SELECT `users`.* FROM `users` LIMIT 1 OFFSET 0

希望最后一个查询不会在任何地方使用。

我只用简单的例子说明,但是我的应用程序执行带有更多连接和包含的大型查询。

可能会因不必要的查询而降低性能。

这只发生在will_paginate'3.0.3'

之后

是错误/功能吗?如何避免这种额外的查询?

2 个答案:

答案 0 :(得分:0)

为了防止will_paginate为计数生成自己的查询,请使用total_entries参数:

@users = User.all
entries = @users.size
@users.paginate(:page => params[:page], :per_page => 20, :total_entries => entries)

答案 1 :(得分:0)

由于rails的查询延迟执行,

will_paginate正在进行额外的查询。以下是the method

的实施
def page_entries_info(collection, options = {})
  model = options[:model]
  model = collection.first.class unless model or collection.empty? # <= this line
  ...
end

如果在执行该行之前尚未加载collection,则rails会对collection.firstcollection.empty?进行额外查询。解决方案是您传递模型,以便will_paginate不必评估它:

page_entries_info @users, model: 'user'