published: 4th of January 2021
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.
The following software was used in this post.
Add the Pagy gem to your Gemfile
# Gemfile
gem 'pagy', '~> 3.5'
Then use bundle to install the gem.
bundle install
Include the Pagy backend into the app/controllers/application_controller.rb file.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include Pagy::Backend
end
Include the Pagy frontend into the app/helpers/application_helper.rb file.
# app/helpers/application_helper.rb
module ApplicationHelper
include Pagy::Frontend
end
Copy 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:
This template is i18n-ready: if you dont use i18n, then you can replace the pagy_t calls with the actual strings ("‹ Prev", "Next ›", "…").
- 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.
# app/views/shared/paginator.html.erb
<% 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.
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
end
In 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.
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.
https://github.com/ddnexus/pagy
https://ddnexus.github.io/pagy/how-to#quick-start