Rails 6 Database Record Pagination with Pagy
Published: 2021-01-04
Intro
In this post I will outline a method the paginate database records in a Rails 6 app using the Pagy. gem. I will also cover the process of styling the paging navbar with bootstrap and font awesome icons.
Software
The following software was used in this post.
- Rails - 6.0.3.4
- Pagy - 3.5
- Bootstrap - 5.0.0-beta1
- Font Awesome (Free) - 5.15.1
Installation
Add the Pagy gem to your Gemfile
# Gemfile
gem 'pagy', '~> 3.5'Then use bundle to install the gem.
bundle installConfiguration
Include the Pagy backend into the app/controllers/application_controller.rb file.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include Pagy::Backend
endInclude the Pagy frontend into the app/helpers/application_helper.rb file.
# app/helpers/application_helper.rb
module ApplicationHelper
include Pagy::Frontend
endCopy the pagy.rb configuration file from here to your config/initializers/ directory.
This file is where you apply some of the customization for Pagy and also enable any extras.
# config/initializers/pagy.rb
# Uncomment this line to enable bootstrap.
require 'pagy/extras/bootstrap'
# Return 25 records per page.
Pagy::VARS[:items] = 25
# Change to layout of the paginator nav bar.
Pagy::VARS[:size] = [1,2,2,1]To use font awesome icons create a partial paginator.html.erb template file in the app/views/shared/ directory.
I used the template from here. Replacing the pagy_t calls with the Font Awesome icon HTML as strings I want to use.
Here is a quote from the docs:
https://github.com/ddnexus/pagy/blob/master/lib/templates/bootstrap_nav.html.erb
For Example:
From: pagy_t('pagy.nav.prev')
To: '<i class="fas fa-angle-left"></i>'
The complete template is below.
<% link = pagy_link_proc(pagy, 'class="page-link"') %>
<nav aria-label="pager" class="pagy-bootstrap-nav" role="navigation">
<ul class="pagination">
<% if pagy.prev %>
<li class="page-item prev"><%= link.call(pagy.prev, '<i class="fas fa-angle-left"></i>', 'aria-label="previous"') %></li>
<% else %>
<li class="page-item prev disabled"><a href="#" class="page-link"><%= '<i class="fas fa-angle-left"></i>' %></a></li>
<% end -%>
<% pagy.series.each do |item| %>
<%# series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] %>
<% if item.is_a?(Integer) %>
<li class="page-item"><%= link.call(item) %></li>
<% elsif item.is_a?(String) %>
<li class="page-item active"><%= link.call(item) %></li>
<% elsif item == :gap %>
<li class="page-item disabled gap"><a href="#" class="page-link"><%= '<i class="fas fa-ellipsis-h"></i>' %></a></li>
<% end %>
<% end %>
<% if pagy.next %>
<li class="page-item next"><%= link.call(pagy.next, '<i class="fas fa-angle-right"></i>', 'aria-label="next"') %></li>
<% else %>
<li class="page-item next disabled"><a href="#" class="page-link"><%= '<i class="fas fa-angle-right"></i>' %></a></li>
<% end %>
</ul>
</nav>Now, Because we altered an initializer, restart your rails server to apply the changes.
Usage
In the controller actions that require paging. Wrap you queries in pagy calls.
# app/controllers/devices_controller.rb
class DevicesController < ApplicationController
def index
@pagy, @devices = pagy(Devices.all)
end
endIn the associated views render the paginator partial template created in a previous step.
# app/views/devices/index.html.erb
<%= render partial: "shared/paginator", locals: { pagy: @pagy }%>And that's it. Behold the blazing fast beauty of Pagy.
Outro
In this post we added pagination to a Rails 6 app using the Pagy gem. We also used Bootstrap to style the paginator and used Font Awesome icons for the navigators and seperator.
Links
https://github.com/ddnexus/pagy
https://ddnexus.github.io/pagy/how-to#quick-start