← til

Building pagination from scratch

November 27, 2019
ruby

Since a lot of my past projects included some sort of single-page application as the frontend and Rails as the backend, I wanted to check how hard would it be to implement pagination without using any gems.

Turns out it's not that hard.

module Pagination
   def self.per_page
     25
   end

   scope :paginate, ->(page){
     offset = [page.to_i - 1, 0].max * per_page
     offset(offset).limit(per_page)
   } do
     def total
       except(:limit, :offset).count(:all)
     end

     def current_page
       page
     end

     def total_pages
       (total.to_f / per_page).ceil
     end

     def more_available?(page)
       page = [page.to_i, 1].max
       page < total_pages
     end
   end
 end

Include this in any Active Record model and it's good to go.

class User < ApplicationRecord
  extend Pagination
end

User.paginate(3) # third page of users

class User < ApplicationRecord
  scope(:admin), -> { where(:role, :admin) }
end

User.admin.paginate(2) # second page of users that are admins

Unlike most popular pagination libraries for Rails, this implementation does not deal with the view layer, since it's assumed that this is going to be implemented within the SPA.