pagination_links_remote

Railsの機能にページネーションを行なうPaginatorってのがありますが,これのremote(Ajax)版.例としてはなんか会員の一覧を出すときとか.

まず普通にページネーションをするときにはcontrollerに

@member_pages, @members = paginate(:members, :order => 'id')

と書けば@member_pagesにPaginatorオブジェクト,@membersにそのページに格納されるMemberモデルのリストが入ってます.
後はビューで

<%= pagination_links(@member_pages) %>

と書けば勝手にページ間リンクを生成することができます.

ただこれだと,普通のリンクになってしまい,検索結果の一覧のページングをしようとしたときに検索条件が保持できないじゃんってなことになりました.考えられる対応策としては,セッション使う,GETで無理くり,とAjaxでリストを更新.てな感じのが思いついたんですが,ここではAjaxを採用.ということにしてしまいました.こうしとけば,検索条件のところはほとんど何もしなくていいかなぁという単純な感じですが.

というわけで,
http://wiki.rubyonrails.com/rails/pages/How+to+Paginate+With+Ajax
http://techno.hippy.jp/rorwiki/?How+to+Paginate+With+Ajax
の二つを参考にAjax版を準備.

この中の一番下を参考に

module ActionView
  module Helpers
    module PaginationHelper
      def pagination_links_remote(paginator, page_options={}, ajax_options={}, html_options={})
        name = page_options[:name] || DEFAULT_OPTIONS[:name]
        params = (page_options[:params] || DEFAULT_OPTIONS[:params]).clone

        pagination_links_each(paginator, page_options) do |n|
          params[name] = n
          ajax_options[:url] = params
          link_to_remote(n.to_s, ajax_options, html_options)
        end
      end
    end # PaginationHelper
  end
end

こんな感じで,ヘルパを拡張.で,この書き方だとAjaxで書いたとして,その一覧が表示されたactionと検索用のactionが別の場合に,URIを変更しないといけなくなる.上を見るurlがparamsで上書きされてる.ってことはpage_options[:params]にlink_to_remoteで書いていた:url項を書いてあげればオッケーてなことに.
こんな感じでビューにページネーションリンクを書く.

<%= pagination_links_remote(@pages,
                           {:window_size=>10, :params=>{:action => 'search'}},
                           {:update=>'list_area', :submit=>'search_form'})%>

自分の場合だと通常のパラメータに検索条件をプラスしたかったので,ajax_optionsに

:submit=>'search_form'

と書いてある.こうするとAjax.UpdatorのparametersにForm.serialize('search_form')された結果が入るので,要件を満たして万々歳.