2012-09-30

Railsでkaminariを使ってページネーションを実装する

Railsでのページネーションの導入に関して とても丁寧に手順が書かれたサイト があったので、それを見ながら実装するまで。

インストール

Kaminariというgemがページネーションの実装に利用できるよう。
Gemfileに「gem 'kaminari'」と追加記述し、「bundle install」。

Modelの設定

当該のモデルに、1ページあたりに出力するインスタンスの数を指定する。 とりあえず、Modelファイルの上部のほうに、

# 1ページに表示する件数の設定(Kaminari)
pagination_per 10

と記述。

Controllerの設定

コントローラには、Modelからページネーションを伴って出力したい情報の取得をして、変数に格納している箇所にメソッドを追加する

@entries = Entry.order('created_at DESC').page params[:page]

Viewの設定

<% @entries%>

のように出力していた箇所を

<% paginate @entries%>

にした。

これで一通りの設定は終わったはずなのでとりあえず、実行。その結果...

Routing Error
undefined method `paginates_per' for #<Class:#########>
Try running rake routes for more information on available routes.

Routing Errorが起こりました!

多分、kaminariをインストールしてから再起動していないのが原因か?と思い、とりあえずRails serverを再起動。再び実行。その結果…

NoMethodError in …
undefined method `current_page' for #<Enumerator:############>

NoMethodErrorが起こりました!

current_pageメソッドが存在しない?よくわからない。Google先生に色々と聞いた結果、ビューファイルでの書き方が間違っていたよう。

さっきまでは、

<% @entries.each do |entry| %>

となっている箇所を、

<% paginate @entries.each do |entry| %>

とやっていたが、これがそもそも間違っていた。

正しい(?)書き方は以下。

<div>
  <% @entries.each do |entry| %>
   …@entriesの出力操作
  <% end %>
</div>
<% paginate @entries %>

divじゃなくてもなんでもいいのだけれど、@entriesオブジェクトをeachで回し終わったあとに書くべきだったよう。

そうこうして、ページネーション自体の実装はできたのだけれど、デザインが明らかに崩れてしまっている。

2012-09-30-07-01.png
2012-09-30-07-01.png

オプションをつけたりしてみたのだけれど、あんまり変わらない。再びGoogle先生の元へ。

どうやら、twitter-bootstrapを利用しているために、デザインが崩れてしまっている用。詳細は以下の記事に書かれている。

これを解消するために、twitter-bootstrap-kaminari-viewsというライブラリを導入した。
githubからcloneして、views/以下のkaminariディレクトリを、app/views/以下に置くだけ。

さらに、先ほど参考にさせていただいた2つのブログにも書かれているように config/locale/ja.yml ファイルを編集して出力文字を変更した。 結果は以下。

2012-09-30-07-02.png
2012-09-30-07-02.png

良い感じになった!
ただ、ページネーションリストが左によってしまっているので、divで囲って text-align:center を付与。

<div style='text-align:center;'>
  <%= paginate @mails %>
</div>

こんなに簡単にページネーションが実装できるとは!!