今回はKaminariを用いたページネーション機能の実装まとめを紹介したいと思います。全てのコンテンツを1ページに表示しようとした場合、ページ読み込み速度といったパフォーマンスやユーザビリティへの低下にも繋がってしまいます。そのためコンテンツが既に膨大である、または今後増えていく想定である場合は、Kaminariを用いてページネーション機能を導入することをおすすめします。
ページネーションとは

ページネーションとは、投稿一覧や検索結果一覧といった複数のコンテンツを複数ページに分割する機能です。ページネーション(pagination)を直訳すると、「ページ割り」や「丁付け」といった意味になります。
Kaminariとは
Kaminariとは、先程紹介したページネーション機能を簡単に作成することができるgemになります。RubyとRailsの最新バージョン(現時点でRuby3.0とRails6.1)にも対応しており、アップデートも日頃行われているため安心して使えるgemの1つと言えるでしょう。
Kaminari
A Scope & Engine based, clean, powerful, customizable and sophisticated paginator for modern web app frameworks and ORMs
最新のWebアプリフレームワークおよびORM向けのスコープとエンジンベースのクリーンで強力なカスタマイズ可能で洗練されたページネーター
参考: Kaminari
Kaminariの特徴
クリーン
Does not globally pollute Array, Hash, Object or AR::Base.
Array、Hash、Object、またはAR :: Baseをグローバルに汚染しません。
使いやすい
Just bundle the gem, then your models are ready to be paginated. No configuration required. Don’t have to define anything in your models or helpers.
gemをインストールするだけで、モデルにページを追加する準備が整います。設定は必要なく、モデルやヘルパーにも何も定義する必要はありません。
シンプルなスコープベースのAPI
Everything is method chainable with less “Hasheritis”. You know, that’s the modern Rails way. No special collection class or anything for the paginated values, instead using a general AR::Relation instance. So, of course you can chain any other conditions before or after the paginator scope.
「Hasheritis」の少ないメソッドチェーンが可能です。これはモダンなRailsの方法です。特別なコレクションクラスなどページ化された値には何もありませんが、代わりに一般的なAR :: Relationインスタンスを使用します。したがって、ページネータースコープの前後に他の条件を連鎖させることができます。
カスタマイズ可能なエンジンベースのI18n対応ヘルパー
s the whole pagination helper is basically just a collection of links and non-links, Kaminari renders each of them through its own partial template inside the Engine. So, you can easily modify their behaviour, style or whatever by overriding partial templates.
ページネーションヘルパー全体は基本的にリンクと非リンクのコレクションにすぎないため、Kaminariはエンジン内の独自の部分テンプレートを介してそれぞれをレンダリングします。したがって、部分テンプレートをオーバーライドすることで、動作やスタイルなどを簡単に変更できます。
ORMとテンプレートエンジンにとらわれない
Kaminari supports multiple ORMs (ActiveRecord, DataMapper, Mongoid, MongoMapper) multiple web frameworks (Rails, Sinatra, Grape), and multiple template engines (ERB, Haml, Slim).
Kaminariは、複数のORM(ActiveRecord、DataMapper、Mongoid、MongoMapper)、複数のWebフレームワーク(Rails、Sinatra、Grape)、および複数のテンプレートエンジン(ERB、Haml、Slim)に対応しています。
モダン
The pagination helper outputs the HTML5 <nav> tag by default. Plus, the helper supports Rails unobtrusive Ajax.
ページネーションヘルパーは、デフォルトでHTML5 <nav>タグを出力します。さらに、ヘルパーはRailsの控えめなAjaxをサポートします。
ページネーション機能の実装手順
ではここからKaminariを用いたページネーション機能を実装してみます。
新規アプリケーションの立ち上げ
まずは以下のコマンドで新規アプリケーションとデータベースを作成します。
% rails new kaminari-demo -d mysql
% rails db:create
今回開発するアプリケーションの環境は以下のようになります。
- アプリケーション名: kaminari-demo
- Rails: 6.0.4
- Ruby: 2.6.5
- DB:MySQL
Kaminariのインストール
次にKaminariをインストールします。Kaminariの特徴にも記載しましたが、gemをインストールするだけで導入が完了するため非常に便利です。
gem 'kaminari'
% bundle install
scaffoldで雛形を作成
続いて、scaffoldの機能を用いてアプリケーション全体の雛形を作成します。
% rails g scaffold post title:string
% rails db:migrate

サーバーを立ち上げlocalhost:3000/postsにアクセスしてみましょう。現段階ではデータが何も登録されていないため、何も表示がされていないはずです。

データの投入
次にデータの投入を行います。データ投入にはseed_fuを使用します。
gem 'seed-fu'
% bundle install
% mkdir db/fixtures
% mkdir db/fixtures/development
% touch db/fixtures/development/01_post.rb
# db/fixtures/development/01_post.rb
Post.seed do |s|
s.id = 1
s.title = 'ワンピース'
end
Post.seed do |s|
s.id = 2
s.title = 'ナルト'
end
Post.seed do |s|
s.id = 3
s.title = 'BLEACH'
end
Post.seed do |s|
s.id = 4
s.title = 'キングダム'
end
Post.seed do |s|
s.id = 5
s.title = 'ガンツ'
end
Post.seed do |s|
s.id = 6
s.title = '亜人'
end
% rails db:seed_fu

サーバーを再起動し、再度localhost:3000/postsにアクセスしてみましょう。すると先ほど登録したデータが表示されているはずです。

ページネーション機能の実装
では本題のページネーション機能の実装に移ります。
今回は1ページに3件のコンテンツを表示することにします。
まずはposts_controller.rbのindexアクションを以下のように編集します。
class PostsController < ApplicationController
before_action :set_post, only: %i[ show edit update destroy ]
# GET /posts or /posts.json
def index
@posts = Post.page(params[:page]).per(3)
end
# 省略
end
続いてページネーションをビューに表示させるため、app/views/posts/index.html.erbを以下のように変更します。ページネーションを表示する該当のコードは<%= paginate @posts %>になります。
<p id="notice"><%= notice %></p>
<h1>Posts</h1>
<table>
<thead>
<tr>
<th>Title</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Post', new_post_path %>
<%# 追記 %>
<%= paginate @posts %>
ブラウザを更新すると、3件のデータとページネーションが表示されているはずです。
デザインの変更
ページネーションの機能自体はできましたが、今のままでは素っ気ないためデザインを変更します。Kaminariにはいくつかのテンプレートがあり、今回はその中からbootstrap4を選んでみます。
The generator has the ability to fetch several sample template themes from the external repository (https://github.com/amatsuda/kaminari_themes) in addition to the bundled “default” one, which will help you creating a nice looking paginator.
ジェネレーターには、バンドルされている「デフォルト」のテーマに加えて、外部リポジトリ(https://github.com/amatsuda/kaminari_themes)からいくつかのサンプルテンプレートテーマをフェッチする機能があり、見栄えの良いページネーターを作成するのに役立ちます。
% rails g kaminari:views THEME # 使用したいテンプレートとTHEME部分を置き換える
参考: Kaminari
以下のコマンドをターミナルに打ち込みます。
% rails g kaminari:views bootstrap4
bootstrapを適用させるため、application.html.erbを以下のように編集します。
<!DOCTYPE html>
<html>
<head>
<title>KaminariDemo</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%# 以下の2行を追記 %>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<%= yield %>
</body>
</html>
ブラウザを更新すると、bootstrapが適用されたページネーションが表示されているはずです。ご自身の好みに合わせてテンプレートを適宜変更してください。

日本語化
現在のページネーションは英語表示されているため(NextやLastなど)、次はこの英語表示を日本語に変換していきます。
まずはデフォルトの言語設定を日本語に変更するため、config/application.rbを以下のように編集します。
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module KaminariDemo
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.0
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
# 追記
config.i18n.default_locale = :ja
end
end
英語表記されているラベルを日本語に設定するには、config/locales/ja.ymlに設定を書き込む必要があります。以下のように、ja.ymlの作成と設定コードを貼り付けます。
% touch config/locales/ja.yml
ja:
views:
pagination:
first: "« 最初"
last: "最後 »"
previous: "‹ 前"
next: "次 ›"
truncate: "..."
サーバーを再起動し、再度ブラウザにアクセスしてみると英語表記だった部分が日本語化されているはずです。

配列に対してページャを作成する

まとめ
- ページネーションとは、投稿一覧や検索結果一覧といった複数のコンテンツを複数ページに分割する機能のこと
- Kaminariとは、ページネーション機能を簡単に作成することができるgem
- Kaminariをインストールすることでpageメソッドとperメソッドを使用することができる
- ページネーションを表示するには<%= paginate @posts %>のようにビューに記載する
- Kaminariにはいくつかのデザインテンプレートが用意されている
参考
今回はKaminariを用いたページネーション機能の実装まとめを紹介しました。労力をかけず、簡単にページネーション機能を実装することができるためぜひ導入を検討してみてください。