(适用 3.0 版 will_paginate)
WillPaginate 是 RoR 里很方便的一个分页用的 gem,例如在控制器里面写
@posts = Post.paginate(:page => params[:page])
然后在视图里面写
<%= will_paginate @posts %>
就可以自动给 Post 对象分页显示了。
不过如果你想给一个通过搜索表单返回的搜索结果进行分页,使用 will_paginate 就不那么方便了,因为它不会在它的链接里自动附上搜索参数,这样除非你的模型里面明确定义了搜索方法(参考 https://github.com/mislav/will_paginate/wiki/Simple-search ),否则对一些复杂的搜索条件(例如你需要组合一些搜索条件)就无能为力了。
当然 will_paginate 考虑到了大家的需求,所以你可以通过覆盖它的 WillPaginate::ActionView::LinkRenderer 类里的方法来给它的分页链接添加额外参数。
(这里给出的方式参考了国外网友对 3.0 以下 will_paginate 的 hack)
首先,在 app/helpers 下创建文件 remote_link_renderer.rb:
# This class intends to add extra URL request parameters in pagination links
# Usage:
# <%
# search_params = {:search => @search,
# :page_num => @page,
# :serial => @serial,
# :code => @code,
# :rule => @rule
# }
# %>
# <%= will_paginate @codes, :renderer =>'RemoteLinkRenderer', :remote => search_params %>
#
class RemoteLinkRenderer < WillPaginate::ActionView::LinkRenderer
def prepare(collection, options, template)
@remote = options.delete(:remote) || {}
super
end
private
def link(text, target, attributes = {})
if target.is_a? Fixnum
attributes[:rel] = rel_value(target)
target = url(target)
end
# here to compose key-value pairs to one string like "&key1=value1&key2=value2"
string_remote = @remote.inject('') do |attrs, pair|
unless pair.last.nil?
attrs << %(&#{pair.first}=#{CGI::escapeHTML(pair.last.to_s)})
end
attrs
end
# append the extra parameters to target
attributes[:href] = target.to_s + string_remote
tag(:a, text, attributes)
end
end
然后,在视图文件里,根据你自己的搜索表单修改 search_params 内容
<%
search_params = {:search => @search,
:rule => @rule,
:registered => @registered,
:reservation => @reservation,
:reg_uid => @reg_uid}
%>
<%= will_paginate @posts, :renderer =>'RemoteLinkRenderer', :remote => search_params %>
注意这里特地指定了 :renderer =>'RemoteLinkRenderer' 。这样你的分页链接里面都会附上你在 search_params 里面设定的参数,你就可以在控制器里面对这些参数进行处理了。