大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

Kaminari

ページネーションとは

pagination ・・・ ページ付け、ページを示す数字 weblioより引用

ページ付けとあるように、"ページを持たせる"という認識でOKです。

例えば、多くの人が使う投稿アプリで一覧表示で全ての投稿を表示するとしましょう。 ページネーションなしだと、全ての投稿が1ページの中に表示されてしまいます。 投稿数が10個程だと問題ありませんが、複数人が使うようなアプリで全ての投稿を一度に表示すると、1ページに100, 1000と表示されてしまい、非常に見づらくなります。カオス状態です。。。

しかし、ページネーションを使えば、非常に多くの投稿があっても、1ページに表示する投稿数が決まっています。 よって、カオス状態とならず、数ページにわたって投稿を表示することができます。

kaminari

Railsのgemの1つで簡単にページネーション機能を実装することができます。 なお、今回は掲示板一覧表示機能にページネーション機能を実装します。

英語ですが、Github上で仕様を確認することができますので、こちらも参照してくださいね。 https://github.com/kaminari/kaminari

kaminari導入

インストール方法

まずがkaminariをinstallするためにGemfileに記載

gem 'kaminari'

そしてお決まりbundle install

$ bundle install

コントローラの編集

一覧表示機能なので、indexアクションを編集していきます。 まずは編集前の状態を確認します。

  def index
    @boards = Board.all.includes(:user).order(created_at: :desc)
  end

Board掲示板モデルです。 Board.allでDBに保存されている全ての投稿を参照し取得します。 そしてincludes(:user)で、BoardモデルのユーザーID(user_id)をBoardモデル参照時に同時に参照します。 order(created_at: :desc)で作成された日時が新しい順番で投稿を取得します。

なぜそのようなことをするのかですが、詳しくは自分の別の記事で紹介しているので、よかったらそちらを見ていただけると幸いです。 N + 1問題 - Railsで解説!

上のファイルの編集後がこちら

  def index
    @boards = Board.all.includes(:user).order(created_at: :desc).page(params[:page])
  end

page(params[:page])が出てきました。これがkaminariをインストールすることで使えるメソッドです。 実は、kaminariを導入したことで、パラメータのキーが一つ増えています。

params
=> <ActionController::Parameters {"page"=>"2",,,,

なるほど。どうやらpageキーでどのページかを判別しているようです。 このキーの増加でpage(params[:page])で何ページ目の投稿であるかを取得することが可能となっています。

ビューにpaginateを追加

ページごとの投稿は取得できるようになったので、ページを移動するための実装をしましょう。 見た目は以下のようになります。

image.png

それではビューに以下の文を追加します。

<div class='mb-3'>
  <%= paginate @boards %>
</div>

paginateによって次のページや前のページに移動することができるようになります。

おそらく見た目が画像と違うのでは? 以下のコマンドで表示が同じになると思いますので、ターミナルに打ち込んでみてください。

$ bin/rails g kaminari:views bootstrap4

これで主なページネーションの実装は終了です。 とっても簡単ですよね!

###ページに表示する数を指定

実は、各ページに表示する投稿数は今の時点では25個となっています。 25個はデフォルトで決まっています。 下記コマンドを実行してkaminariのデフォルトを設定をみることができます。

$ rails g kaminari:config

作成されたファイルを見てみると

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
  # config.max_pages = nil
  # config.params_on_first_page = false
end

いろいろな設定が表示されていると思います。 今回はデフォルトのページ数を25から10に変えてみようと思います。

Kaminari.configure do |config|
  # 25から10に変更
  # config.default_per_page = 10
  # 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
  # config.max_pages = nil
  # config.params_on_first_page = false
end

これでページごとに表示される投稿数が10となりました。

しかし、先ほども言いましたように、こちらのファイルはkaminariのデフォルト値を設定するファイルです。 つまり、全体で共通の設定となります。 投稿一覧機能にのみページネーションするのであれば問題ありません。 しかし、投稿に対しコメント機能を実装し、そのコメントに対しページネーションをすると、そのコメントはページごとに10個のコメントを表示することになります。

これを避ける方法があります。 各モデルに対し個別でページごとの表示数を設定するのです。

もしページごとの投稿の表示数を10とする場合、直接モデルに対しその設定を加えます。

class Board < ApplicationRecord
  # specify default per_page value per each board
  paginates_per 20

paginate_perでデフォルト値を上書きすることができます。 コメント機能にページネーションを実装したい場合、コメントのモデルに対し同じようにpaginate_perを書けばいいのです。