Skip to content

Paginating with Kaminari

Ben Bristow edited this page Mar 3, 2018 · 2 revisions

This is a simple solution to paginate JSON according to the HAL Specification. A solution that generates links like this.

So first, start with the view:

# api/v1/posts/index.rabl
object false

child(@posts) do
  extends 'api/v1/posts/show'
end

node(:_links) do
  paginate @posts
end

Then proceed to define the paginate method:

# app/helpers/api_helper
module ApiHelper
  def paginate(collection)
    current_page_num = collection.current_page
    last_page_num = collection.total_pages

    {
      first: first_page,
      previous: previous_page(current_page_num),
      self: current_page(current_page_num),
      next: next_page(current_page_num, last_page_num),
      last: last_page(last_page_num)
    }
  end

  def first_page
    { href: url_for(page: 1) }
  end

  def previous_page(current_page_num)
    return nil if current_page_num <= 1
    { href: url_for(page: current_page_num - 1) }
  end

  def current_page(current_page_num)
    { href: url_for(page: current_page_num) }
  end

  def next_page(current_page_num, last_page_num)
    return nil if current_page_num >= last_page_num
    { href: url_for(page: current_page_num + 1) }
  end

  def last_page(last_page_num)
    { href: url_for(page: last_page_num) }
  end
end

And finally, include the helper in the necessary controllers with:

helper :api

The helper could be included in a Api::BaseController, from which all api controllers inherit.