分享 如何向 Ruby on Rails 分页插件 will_paginate 的链接插入其它参数

tangramor · 2013年10月28日 · 最后由 Peter 回复于 2014年05月19日 · 5230 次阅读

(适用 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 里面设定的参数,你就可以在控制器里面对这些参数进行处理了。

楼主的方案挺好的,

不过我用 ransack,方法用 get,不作任何修改直接就支持了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号