Ruby on Rails 2.0.1に対応

さて、待望のRuby on Rails 2.0.1がリリースされたので、自作アプリもこれに対応してみることにした。
とりあえず、アップデート。

# gem update rails -y

ただし、これは俺の環境だけかもしれないが、rubygemsの依存関係に任せておくと、Rails2.0では必須であるはずのActiveResourceがインストールされない。よって、これも別途インストールする。

# gem install activeresource

お決まりの更新作業を実施。config/environment.rbのRAILS_GEM_VERSIONを書きかえる。

RAILS_GEM_VERSION = '2.0.1' unless defined? RAILS_GEM_VERSION

で、アップデート。

$ rake rails:update

Javascriptのライブラリとかいろいろ変更される。

で、さっそく起動してみたら、これが動かない。

NoMethodError (undefined method `paginate' for #):

paginateが無い?ちょいと調べてみると、paginationはRails2.0からプラグインになって標準でバンドルされなくなったらしい。RC時代から2.0を見ている人々からすれば常識レベルの知識のようだ。まいったぜ。

classic_paginationプラグインをインストールすれば、そのまま使えるようになる。

$ ruby script/plugin install http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/classic_pagination/

これで動くようにはなるのだが、インストール時のメッセージに気になる一文がある。

This code was extracted from Rails trunk after the release 1.2.3.
WARNING: this code is dead. It is unmaintained, untested and full of cruft.

There is a much better pagination plugin called will_paginate.

classic_paginationは今後メンテナンスされないから、will_paginateを使うべし、とのこと。より優れたAPIになっていると主張しているし、どうせ対応しなければならないのだから早いほうがいい。というわけで、これを入れてみることにした。

2008/05/08追記:will_paginateのインストール方法は変更されており、下記の方法はもう古い。詳しくはこちらのエントリで。

とりあえず、リポジトリ登録するか・・・。

$ ruby script/plugin discover -n

なんと、-nオプション*1が効かない!大量に見つかるリポジトリ一つ一つにyキー押して応答しろってか?ありえん。

仕方がない、直接指定だ。

$ ruby script/plugin install svn://errtheblog.com/svn/plugins/will_paginate

ネットワークがセキュリティガチガチでsvn://を通してくれない場合は、httpで落とすしかない。非常に頭の悪い方法*2で探してみたら、どうやらhttp://tools.assembla.com/svn/breakout/breakout/vendor/plugins/will_paginate/から落とせるらしいことがわかった。

$ ruby script/plugin install http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/will_paginate/

インストール成功。

ようやくソースコードの修正に入ることができる。もっとも、やることは簡単だ。まず、コントローラ内のpagination表示する直前のアクション(ここではEntriesController#list)で、次のように書く。

def list
  #@entry_pages, @entries = paginate :entries, :per_page => 10, :order => 'created_at desc'
  @entries = Entry.paginate :page => params[:page], :per_page => 10, :order => 'created_at desc'
end

比較用に古いpaginationのコードもコメントアウトして併記した。

paginateメソッドは、:orderを見ればわかると思うが、基本的にActiveRecordのfindメソッドと同じように扱える。:per_pageは1ページあたりの表示件数、そして:page => params[:page]は、どうやら表示するページ番号を渡しているらしい。:pageというパラメータ名がどこから表れたのか疑問だったが、viewでつかうwill_paginateヘルパーが勝手にpageパラメータにページ番号を渡してくるので、とにかくこう書くものだと思っていてよさそうだ。

で、そのwill_paginateなのだが、view(ここではapp/views/entries/list.rhtml)で次のように使う。

<%= will_paginate @entries %>

これだけ。

あと、これは別にやらなくてもいいオマケ的作業なのだが、will_paginateのREADME(vendor/plugins/will_paginate/README)に「こんなCSS定義しとくといいんじゃね?」というサンプルが載っているので、これをpublic/stylesheets/paginate.cssとして保存し、layouts(ここではapp/views/layouts/entries.rhtml)のヘッダで読み込ませておく。

<%= stylesheet_link_tag 'paginate' %>

では、表示。

おおっ、いいじゃん、いいじゃん?

途中からwill_paginateの話になってしまったが、これにてめでたくRuby on Rails 2.0.1対応が終了。他にもいろいろお作法が変わったりしてるだろうから完璧ではないが、とりあえず動く。paginationはwill_paginate以外にもいろいろありそうなので、今後試していきたい。

*1:--no-prompt。対話無しに、新しいリポジトリを片っぱしから登録していくはずのオプション。

*2:ruby script/plugin discover -lで調べたリポジトリ中、httpなところを片っ端からaddして検索した・・・。