こんにちは、鈴木です。
一覧画面に「<< | < | 1 | 2 | 3 .. 10 | 11 | 12 ... 98 | 99 | 100 | > | >>」のようなリンクが付いていることは多いですね。
ページング、ページネーション、ページャー、・・・などと呼び方は色々ありますが、ここでは「ページング」と呼ぶことにします。
今回はページングを実現するライブラリ kaminari をご紹介します。
- kaminari (https://github.com/amatsuda/kaminari)
kaminari の導入
Gemfile に以下の行を追加します。
1 |
gem 'kaminari' |
bundle install します。
1 |
bundle install |
これで準備は完了です。
kaminari を導入すると、モデルクラスに page というスコープが定義されます。
これはページングにおける「何ページ目」を指定するためのスコープです。
1 2 |
# 3 ページ目を取得. User.page(3) |
また、per メソッドでページあたりの件数を指定することができます。
1 2 |
# ページあたり 10 件として 3 ページ目を取得. User.page(3).per(10) |
ページングする
コントローラ
まずはコントローラを実装します。
page の引数を固定にしても意味はありませんので、リクエストパラメータで指定されたページ番号 ( params[:page] ) を指定するようにします。
ページあたりの件数は 10 の固定とします(画面上で指定できるようにしても良いでしょう)。
1 2 3 4 5 6 7 |
class UsersController < ApplicationController def index @users = User.page(params[:page]).per(10).order(:id) end end |
View
View では paginate メソッドを使用して、ページング用のリンクを表示することができます。
1 |
<%= paginate(@users) %> |
画面上では以下のようなリンクが表示されます(スタイルシートは何も効いていない状態なのでシンプルな見た目です)。
以上が kaminari を用いてページングを実現する最小の手順です。
page_entries_info メソッドで「○件から○件まで表示」のような文字列を表示することができます。
1 |
<%= page_entries_info(@users) %> |
以下のように表示されます。
デフォルトの設定を変更する
設定ファイルでの指定
以下のコマンドを実行すると、kaminari の設定ファイル ( config/initializers/kaminari_config.rb ) が生成されます。
1 |
rails generate kaminari:config |
生成されたファイルを開くと以下のようになっていますので、デフォルトから変更したい項目の設定を修正します。
1 2 3 4 5 6 7 8 9 10 |
Kaminari.configure do |config| # config.default_per_page = 25 # config.max_per_page = nil # config.window = 4 # config.outer_window = 0 # config.left = 0 # config.right = 0 # config.page_method_name = :page # config.param_name = :page end |
各設定項目の意味は以下の通りです。
- default_per_page
デフォルトのページあたりの表示件数(デフォルトは 25)。 - max_per_page
ページあたりの表示件数の最大(デフォルトは nil、つまり無制限)。 - window
表示中のページの左右何ページ分のリンクを表示するかを指定します(デフォルトは 4)。上記画像はデフォルトの 4 で、11 ページを表示しているところです。11 の左右それぞれ 4 ページ分のリンクが生成されています。 - outer_window
先頭ページ、及び最終ページから何ページ分のリンクを表示するかを指定します(デフォルトは 0)。left、right が指定された場合は、そちらの値が優先されます。 - left
先頭ページから何ページ分のリンクを表示するかを指定します(デフォルトは 0)。上記画像は 3 を指定した場合です。 - right最終ページから何ページ分のリンクを表示するかを指定します(デフォルトは 0)。上記画像は 2 を指定した場合です。
- page_method_name
モデルに追加されるページ番号を指定するスコープの名前(デフォルトは page)。 - param_name
ページ番号を渡すために使用するリクエストパラメータの名前(デフォルトは page)。
デフォルトの指定は、モデルや View で上書きすることができます。
モデルでの指定
モデルクラスごとにデフォルトを指定することもできます。
1 2 3 4 5 6 |
class User < ActiveRecord::Base paginates_per 10 max_paginates_per 30 end |
View での指定
上記設定は View で使用する paginates メソッドで個別に指定することもできます。
1 |
<%= paginates(@user, :outer_window => 3) %> |
:params オプションで追加の URL パラーメータの値を指定することもできます。
1 |
<%= paginates(@user, :params => {:other_param => 'taro'}) %> |
日本語化
ロケールファイルの記述例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
ja: views: pagination: first: 先頭 last: 最終 previous: 前ページ next: 次ページ truncate: "..." helpers: page_entries_info: one_page: zero: "<b>該当データがありません。</b>" one: "<b>1件中 1-1 件を表示</b>" display_entries: '%{entry_name}の1-%{count}件を表示中 / 合計%{count}件' more_pages: display_entries: '%{entry_name}の%{first}-%{last}件を表示中 / 合計%{total}件' |
※helpers. page_entries_info.more_pages.display_entries の値の中で entry_name を使用していますが、表示される時に「ユーザs」のようになってしまい、意図通りに表示させることができませんでした。コードを見たところ、検索結果が複数件の場合は entry_name の値に pluralize が適用される(つまり 'ユーザ'.pluralize => 'ユーザs' となる)ことが原因のようでした(現時点で)。
View ファイルのカスタマイズ
View ファイルをカスタマイズしたい場合は、以下のコマンドでテンプレートを生成することができます。
1 2 3 4 5 6 7 8 |
> rails generate kaminari:views default create app/views/kaminari/_page.html.erb create app/views/kaminari/_gap.html.erb create app/views/kaminari/_first_page.html.erb create app/views/kaminari/_paginator.html.erb create app/views/kaminari/_last_page.html.erb create app/views/kaminari/_prev_page.html.erb create app/views/kaminari/_next_page.html.erb |
引数の「default」は使用するテーマです。テーマを指定せずにコマンドを実行すると、使用可能なテーマ一覧を確認することができます。
1 2 |
# 指定可能なテーマを確認. rails generate kaminari:views |
複数のテーマのテンプレートを生成した場合は、paginate メソッドの :theme オプションで使用するテーマを指定することができます。
1 |
<%= paginate(@users, :theme => 'admin') %> |
テンプレートは HAML 形式で生成することもできます。
1 |
rails generate kaminari:views default -e haml |
まとめ
Rails2.x 時代は will_paginate という大変有名なプラグインがありました。
後発の kaminari は、will_paginate よりモデルを汚さない、HTML5 に対応している、という理由で好まれることが多いと感じています。
Comments
zero: "No %{entry_name} found"
one: "Displaying <b>1</b> %{entry_name}"
other: "Displaying <b>all %{count}</b> %{entry_name}"
ページネーションの訳を教えていただけないでしょうか?すいません、仕事訳さないといけないのですが、よく分からなくて。よろしくお願いいたします。
日本語での文言については、私から「これなら大丈夫です」とは言えません。
お仕事で訳されるということなので、なおさらです。
世の中の一般的なサイトも参考にいくつか案を考え、
お仕事を依頼されたお客様に選んでいただいてはどうでしょう。