LoginSignup
1
2

More than 5 years have passed since last update.

will_paginateのurlを変更する

Posted at

発生した問題

will_paginateをrailsアプリに組み込んでいるが、paramsを用いた検索を併用すると・・・2ページ目以降のurlがおかしい?

例えば、/search/myloversというページでparamsを用いたDB検索を行う。そのとき、発行されるurlは、
 /search/mylovers?age_gte=20&age_lte=25&occupation=model
といった感じになる。しかし、このとき、will_paginateを用いて複数ページに結果を分割していたとして、will_paginateが作成する「次へ」ボタンのurlは、
 /search/mylovers?age_gte=20&age_lte=25&occupation=model&page=2
とはならないときがある。

原因

url_forヘルパーがroute.rbの設定に依存すること

will_paginateはurl_forヘルパーを用いてurlを作成し、それをボタンに埋め込む。しかし、もしrails側のroutes.rbにおいて、
 get search/mylovers/:occupation => search/index
みたいな設定をしていた場合(つまり、params[:occupation]をurl内に組み込んでいた場合)、url_forヘルパーは、
 /search/mylovers?age_gte=20&age_lte=25&occupation=model
のかわりに、
 /search/mylovers/model?age_gte=20&age_lte=25
を返してくる。つまり、routes.rbでの設定を逆に解釈する。routes.rbでは、「もし、/search/myloversの後ろになんかひっついてきたら、それをparams[:occupation]として解釈してね」という指示を与えたつもりが、url_forヘルパーは気を回して「もし、params[:occupation]が渡ってきたら、search/mylovers/の後ろに引っ付けるようにしよう」としてしまう。

 基本的にはそれでも問題ない場合が多いが、例えば、params[:occupation]が配列形式である場合には、このurl_forヘルパーは壊れる。
 /search/mylovers?occupation=model&occupation=nurse
というurlを発行すると、url_forヘルパーは、
 /search/mylovers/modelnurse
を返してくる。もちろんこれは無効urlとなり、ページネーションが動作しないことになる。

解決策

 will_paginate内で作られるurlに問題があるので、gemのオーバーライドをする。オーバーライドとは、既存のメソッドの上書きのようなもの。オーバーライドのやり方は以下のステップ。

  • 上書き用のファイルを用意
  • 上書きするメソッドの位置を特定
  • 上書き内容を書く

 今回は、app/helper内にファイルを用意した。次に、gem内部のどのメソッドを修正したいか(するべきか)を特定する。今回の場合、発行されるurlを変更したいので、urlを作成しているメソッドを探す。見つけたら、書き換えるメソッドのある場所を、module名::class名で指定する。今回はmoduleがネストしていたので、WillPaginate::ActionView::LinkRenderer。書き換えるメソッド名は「url(page)」。ここまでの段階で、上書きファイルの内容は下のようになる。

paginatehelper.rb
module PaginationHelper
 class SearchPagination < WillPaginate::ActionView::LinkRenderer
  def url(page)#書き換えるメソッドと同じ名前に
    #処理
  end
 end
end

あとは、処理の中で好きに書けば良い。今回はrequest.full_pathを使って現在のurlを取得し、お尻にparams[:page]をつける処理にした。

あとは、viewのwill_paginateのrendererオプションにオーバーライドしたいやつを指定。

index.html.erb
<%= will_paginate @mylovers, renderer: PaginationHelper::SearchPagination

これで完了。will_paginateはrendererオプションでオーバーライドして色々カスタマイズができる。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2