はじめてのRuby on Rails、トラブル記録
スポンサーサイト

一定期間更新がないため広告を表示しています

posted by スポンサードリンク | | - | - | - |はてなブックマーク - スポンサーサイト
will_paginateで検索&ページ切り替え
ユーザーの検索をして、検索結果の件数がX件以上の場合には次のページ、というのがやりたかったので
ページ切替のプラグインとして有名なwill_paginateを使ってみました。

【本家】http://wiki.github.com/mislav/will_paginate

1ページめは普通に出るんだけれど、2ページめに検索条件をうまく引き継げなくて、
ActiveRecord::RecordNotFound (Couldn't find Server with ID=search)
というエラーがずっと解決できなかったですよ。
検索条件が1つとかならすぐにできたんだけど、何個もある複雑な検索でどうやればいいかググってもいい方法が見つからず……ショック
でも、なんとかやり方を編み出した!

ということで最初から順番いきます。

【1】will_paginateのインストール


will_paginateはgemでのみ配布の模様。
gem install mislav-will_paginate
以前は「gem install will_paginate」だったらしいけれど、これはもう更新されていないようなので、「mislav-」をつけないと古いまんまです!

【2】environment.rbの設定


config/environment.rbの一番下に以下のコードを追加して、will_paginateが使えるようにします。
require 'will_paginate'


【3】検索フォーム用ビュー


user/index.htmlに検索フォームを置きました。methodはgetで!
<% form_for :user, :url => {:action => 'search', :method => 'get'} do |f| -%>

 
<%= f.label :nickname %>:

 
<%= f.text_field :nickname %>


 
<%= f.label :sex %>:

 

  <%= f.radio_button :sex, 'any', :checked=>'checked' %><%=h t('any') %>
  <%= f.radio_button :sex, 'M' %><%=h t('male') %>
  <%= f.radio_button :sex, 'F' %><%=h t('female') %>
   


 
<%= f.label :age %>:

 

  <%= f.select :age_from, options_for_select(%w(- 18 19 20 21 22 23 24 25…以降略)) %>
  <%=h t('to') %>
  <%= f.select :age_to, options_for_select(%w(- 18 19 20 21 22 23 24 25…以降略)) %>
 


 <%= f.submit t('Search') %>
<% end -%>


【4】コントローラー


def search

  # 検索フォームから入力された内容を@keyに入れてビューに渡す
  @key = params[:user]

  # 検索キーの設定
  # フォームに入力のあった項目のみ検索条件に追加されていくようにする

  key = "nickname LIKE :nickname" unless params[:user][:nickname] == ""

  unless params[:user][:sex] == "any"
   if key == nil
    key = "sex = :sex"
   else
    key = key + " AND sex = :sex"
   end
  end

  unless params[:user][:age_from] == "-" && params[:user][:age_to] == "-"
   age_from = get_date_from_age(params[:user][:age_from])
   age_to = get_date_from_age(params[:user][:age_to])
   # get_date_from_ageは年齢から日付を出す自作のヘルパーメソッド

   # fromがtoより大きければtoとfromを入れ替える
   age_from, age_to = age_to, age_from if age_from > age_to

   if key == nil
    key = "birthday BETWEEN :age_from AND :age_to"
   else
    key = key + " AND birthday BETWEEN :age_from AND :age_to"
   end
  end

  @users = User.paginate(:page => params[:page],
   :per_page => 5,
   :conditions => [ key, # keyに検索条件文が入ってる
    { :nickname => "%"+ params[:user][:nickname]+"%",
     :sex => params[:user][:sex],
     :age_from => age_from, :age_to => age_to,
     }])

  respond_to do |format|
   format.html
   format.xml { render :xml => @users }
  end
   
end


【5】検索結果表示用ビュー


検索結果自体は普通に<%=h user.nickname %>とかでいいらしい。
ページ切替部分の表示は以下のコード。
<%= will_paginate @users, :prev_label=>'prev', :next_label=>'next', :params => {:user =>@key} %>
検索フォームのところでform_for :userにしてたのでここは:params=>{ :user => @key }で最初に入力された内容がすべてこの中に入るようにしました。

検索フォーム用ビュー: <%= form_for :user %>
         down
コントローラー: @key = params[:user]
         down
検索結果表示ビュー(ページ切替部): :params => { :user => @key }


という流れで条件がちゃんと引き継げるようにしたら、最初は1ページめだけしかちゃんと表示されないで2ページめに行こうとするとエラーになってたのが、ちゃんと2ページめ以降も表示されるようになった楽しい

【6】検索ページ用のルーティング設定


ちなみに……検索用のsearchクラスを作ったので、routes.rbに以下を追加しないとエラーが出ます。
map.search '/search', :controller => 'users', :action => 'search'


こう書くと、さらっとできたように見えるけど、実際にはここまで来るのにめっちゃ苦労したのさ……!
力技かな?
良いコードなのかどうなのか判断できるだけの経験がないので、もしかしたらもう少しいい書き方があるのかもしれないけど、とりあえずさらしちゃいます〜。



【参考】
will_paginateのオプション
http://www.katawara.com/2008/04/will_paginate_usage/
posted by トモト | 13:08 | ページ切替(will_paginate) | comments(0) | trackbacks(0) |はてなブックマーク - will_paginateで検索&ページ切り替え
Rails3レシピブック 190の技
Rails3レシピブック 190の技
ついにRails3対応版が出ました!!
WEB+DB PRESS Vol.58
WEB+DB PRESS Vol.58
Rails2系から3への移行時に知りたいことがひとまとまりになっててよかった!色々ググるよりこれを読む方が早い。
Rubyレシピブック 第3版 303の技
Rubyレシピブック 第3版 303の技
Rubyやるならこのリファレンスは必要。
Search this site