Rails APIモードで kaminari を使ってみる

こんにちは!kossyです!




さて、今回はRails APIモードでの kaminari の使い方を備忘録としてブログに残してみたいと思います。




環境

Ruby 2.6.8
Rails 6.0.4
MacOS BIgSur
kaminari 1.2.1



実装

前提としてjbuilder gem が導入されているものとします。

まずはGemfileの編集

# Gemfile

gem 'kaminari'

で bundle install

$ bundle install

次にapp/controllers/concerns/ に pagination.rbという名前でモジュールを定義します。

$ touch app/controllers/concerns/pagination.rb

作成されたファイルを以下のように編集します。

module Pagination
  extend ActiveSupport::Concern

  def pagination(records)
    {
      total_count: records.total_count,
      limit_value: records.limit_value,
      total_pages: records.total_pages,
      current_page: records.current_page
    }
  end
end

Concernとしたのは、複数のcontrollersで使い回すことを想定しているためです。
ページネーションはどのcontrollersからでも要求される可能性のある機能ですので。

次に適当にscaffoldでCRUDを実装します。

$ rails g scaffold Post titie:string body:text

作成・編集されたファイルを適宜変更していきます。

# app/controllers/posts_controller.rb

class PostsController < ApplicationController
  before_action :set_post, only: :show

  include Pagination

  def index
    @posts = Post.page(params[:page]).per(params[:per])

    @pagination = pagination(@posts)
  end

  def show
  end

  private

    def set_post
      @post = Post.find(params[:id])
    end
end
# config/routes.rb

scope format: 'json' do
  resources :posts, only: [:index, :show]
end
# app/views/index.json.jbuilder

json.posts @posts, partial: 'posts/post', as: :post

json.pagination @pagination

次に適当にテストデータを作成します。

$ rails c

1.upto(100) do |i|
  Post.create!(title: "#{i}個目のタイトル", body: "#{i}個目の本文")
end

この状態でサーバーを立ち上げて、Postman等のAPIクライアントで動作確認をしてみます。

pageは2ページ目を、1ページ当たりに表示するレコードの数を5にしてリクエストを送信したため、IDが6 ~ 10のレコードを取得しています。

f:id:kossy-web-engineer:20210717174056p:plain


paginationも問題なく取得できています。(もともと5件テストデータ入ってて105件になってました、、、)

f:id:kossy-web-engineer:20210717174240p:plain

フロント側はパラメータとしてpageやperを送信し、サーバーから返ってきたtotal_count等のプロパティを使って、総件数や現在のページ番号を表示する実装になるかと思います。