kaminariを使って外部APIのページネーションをする
外部のAPIから取得したデータをkaminariを使ってページングするときのメモです。
結論
kaminariのpaginate_arrayメソッドに、以下のように配列とtotal_countを指定することでできる。
@posts = Kaminari.paginate_array(配列, total_count: 総数) .page(現在のページ) .per(各ページ毎の表示数)
具体例
今回は、jsonを出力するAPIを用意し、そのjsonをパースしてページネーションをするということをします。
API
投稿一覧を出力するだけのシンプルなAPIを作成します。 こちらもKaminariをインストール済みとします。
コントローラー
class PostsController < ApplicationController def index @posts = Post.published.page(params[:page]).per(1) respond_to do |format| format.html { render :index } format.json { render 'index.json.jbuilder' } end end end
ビュー(jbuilder)
json.meta do # kaminariのメソッド json.total_pages @posts.total_pages json.current_page @posts.current_page json.total_count @posts.total_count json.limit_value @posts.limit_value end json.data do json.array! @posts do |post| json.id post.id json.title post.title end end
以下のようなjsonが出力されます。
{ "meta":{ "total_pages":2, "current_page":1, "total_count":2, "limit_value":1 }, "data":[ { "id":1, "title":"タイトル1", } { "id":2, "title":"タイトル2", } ] }
ページネーション
コントローラー
class ExternalPostsController < ApplicationController def index require 'net/http' require 'uri' require 'json' end_point = "https://sample.com/posts.json?page=#{params[:page]}" uri = URI.parse(end_point) response = Net::HTTP.get_response(uri) body = JSON.parse(response.body) meta = body["meta"] @posts = Kaminari.paginate_array(body["data"], total_count: meta["total_count"]) .page(meta["current_page"]) .per(meta["limit_value"]) end end
ビュー
- @posts.each do |post| # postを表示する処理 - end = paginate @posts