ページネーション
2008/12/17
前回は、トップページが表示できたところで終わりました。
単体テストは通るでしょうか。
> rake test:units (省略) /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:428:in `load_missing_constant': Expected /home/kuroda/hgrepos/books/kiso_rails/cd-rom/chapter9/ app/helpers/mobile/blog_entries_helper.rb to define Mobile::BlogEntriesHelper (LoadError) (省略)
あれれ、通りませんね。問題の app/helpers/mobile/blog_entries_helper.rb
を見ると次のようになっています。
module Mobile::BlogsHelper end
読者の皆様にまたしても謝らなければなりません。CD-ROM 付属のソースコードにミスがありました。次のように修正してください。本当に済みません。
module Mobile::BlogEntriesHelper end
これで、単体テストは通ります。
次に、機能テストです。
> rake test:functionals (省略) 92 tests, 235 assertions, 4 failures, 13 errors (省略)
ああ、失敗です。
ざっとエラーメッセージを見ると、ページネーション関連でエラーが出ています。
ページネーションは、Rails 2.0 からフレームワーク本体から分離されてプラグインになりました。そのままでは動きません。
Rails 2.0 が出た当時は、classic_pagination プラグインをインストールせよ、と言われていましたが、インストールを試みると…
> ruby script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination svn: ホスト 'errtheblog.com' に接続できません: Connection refused
と拒絶されてしまいます。もはや提供されていないようです。
代替品(性能的には classic_pagination よりも良い)の mislav-will_paginate を使うことにします。
> gem sources -a http://gems.github.com http://gems.github.com added to sources > sudo gem install mislav-will_paginate Successfully installed mislav-will_paginate-2.3.6 1 gem installed Installing ri documentation for mislav-will_paginate-2.3.6... Installing RDoc documentation for mislav-will_paginate-2.3.6...
読者の方からの指摘を受けて、インストール手順に
> gem sources -a http://gems.github.com
を追加しました。mislav-will_paginate プラグインは、標準の gem リポジトリではなく GitHub を通じて配布されています。
config/environment.rb に次のような記述を追加します。。
config.gem 'mislav-will_paginate', :lib => 'will_paginate'
追加する位置は、
Rails::Initializer.run do |config| ... end
の内側です。
では、ひとつずつ潰していきましょう。手始めに、main コントローラから。
> ruby test/functional/main_controller_test.rb
大量の警告とエラーメッセージが出ました。まず、次のエラーを何とかしましょう。
NameError: uninitialized constant MainController::Paginator
オリジナルはこうなっています:
(省略) # 私たちの活動 def activities page = (params[:page] || 1).to_i @activities, count = Article.current_articles('activities', ARTICLES_PER_PAGE, page) @activities_pages = Paginator.new(self, count, ARTICLES_PER_PAGE, page) @number_of_members = Member.count end # ニュース def news page = (params[:page] || 1).to_i @news, count = Article.current_articles('news', ARTICLES_PER_PAGE, page) @news_pages = Paginator.new(self, count, ARTICLES_PER_PAGE, page) end (省略)
これを、このように書き換えます:
(省略) # 私たちの活動 def activities @activities = Article.current_articles('activities').paginate(:page => params[:page], :per_page => ARTICLES_PER_PAGE) @number_of_members = Member.count end # ニュース def news @news = Article.current_articles('news').paginate(:page => params[:page], :per_page => ARTICLES_PER_PAGE) end (省略)
次に、テンプレート activities.rhtml
と news.rhtml
を書き換えます。
オリジナルはこうなっています:
(省略) <% if @activities_pages.page_count > 1 -%> <div class="pagination"> <%= my_pagination_links @activities_pages, :window_size => 9 %> </div> <% end -%> (省略)
activities.rhtml
を次のように書き換えます:
(省略) <%= will_paginate @activities, :previous_label => '前へ', :next_label => '次へ', :inner_window => 2 %> (省略)
news.rhtml
を次のように書き換えます:
(省略) <%= will_paginate @news, :previous_label => '前へ', :next_label => '次へ', :inner_window => 2 %> (省略)
我々が作った pagination_links プラグインと mislav-will_paginate プラグインでは、1ページ目へのリンクの書き方が異なるので、テストを書き換えます。
test/functional/main_controller_test.rb
を開き、a[href=/main/news]
をすべて a[href=/main/news?page=1]
に置換してください。
これで main_controller_test.rb
は通ります。
ただし、次のような警告が大量に表示されます。
DEPRECATION WARNING: truncate takes an option hash instead of separate length and omission arguments.
Rails 2.2 から truncate
メソッドの引数の取り方が変わっています。
Rails 2.1 までは truncate(text, length, omission)
でしたが、Rails 2.2 以降は truncate(text, *args)
となり、文字列の長さは :length
オプションで渡すことになりました。
<%= my_format(truncate(a.body, 20)) %></li>
を、次のように修正します。
<%= my_format(truncate(a.body, :length => 20)) %></li>
再度、すべての機能テストを実行します。
> rake test:functionals (省略) 92 tests, 278 assertions, 4 failures, 8 errors (省略)
エラーの数が 13 から 8 に減りました。
疲れました。本日はここまで。