Paginating Rails with Pagy

Written by gerald-goh | Published 2020/01/08
Tech Story Tags: pagination | tutorial-for-beginners | rubygems | ruby-on-rails | pagy | bulma | programming | software-development

TLDR Pagy is a recent pagination library for Ruby on Rails. It was developed with performance in mind, with the ease to set up on a new or existing Ruby on rails application. The only prerequisite is to ensure your rails app is complete enough to view stored data-sets. In this tutorial, we will see how to build a custom pagination component with rails for pagination. We will build a paginated view of array and non-array data-set. Check out our repository to see how we've set up Pagy.via the TL;DR App

After completing the first built of our rails app application, I decided to take it out for a spin. Using Ruby commands that were initially tested on rails console, I built a seed file to populate the database. There were 2 reasons to seed the database. The first was to get an aesthetic feel of the app filled with data. The second was to see how would the app would scale visually with a huge amount of data.
After filling the database with 161 users, 60 blog post and 49 relationships, one of the pages span vertically to the height of Eiffel tower. You can imagine scrolling a page for a long time. So I went sourcing for a holistic solution to chunk views into a single page. I found Pagy.
Pagy is a recent pagination library for Ruby on Rails. It was developed with performance in mind, with the ease to set up on a new or existing Ruby on Rails application. Also because I used Bulma CSS framework and Pagy was developed to with it.
With the exponential data growth in mind, Pagy is the cream of the crop with it comes to performance and lite resource usage. In comparison to other known pagination gems, Pagy leads the way.

Speed

Memory Utilization

Simplicity

Efficiency

Each dot in the visualization above represents the resources that Pagy consumes for one full rendering. The other gems consume hundreds of times as much for the same rendering.

In this tutorial, we will see how to build a custom pagination component with Rails for paginating large data-sets. We will build a paginated view of array and non-array data-sets.
The only prerequisite is to ensure your Rails app is complete enough to view stored data-sets.
Start by editing your Gemfile by adding the following line.
# ./gemfile

gem 'pagy'
Rails offer standard spots to place initialization code (i.e
/config/initializer
). In the rare event that your application needs to run some code before Rails itself is loaded, add a new file called pagy.rb. In the configuration file add the following lines.
# config/initializer/pagy.rb

require 'pagy/extras/bulma'
require 'pagy/extras/array'
Extras don't define any new module or class, they just re-open the Pagy class and modules, adding the extra methods as they were part of the loaded pagy gem. This neatly separates the core code from the optional extras, still keeping its usage as simple as it were part of the core.
"Pagy::Backend" provides a generic pagination method (pagy) that works with ActiveRecord out of the box. Include the method in ApplicationController so it's reflected on all other controllers.
# app/controllers/ApplicationController.rb

class ApplicationController < ActionController::Base
  include Pagy::Backend
end
"Pagy::Frontend" module provides a few methods to deal with the navigation aspect of the pagination. Include this method in ApplicationHelper.
# app/helper/ApplicationHelper.rb

module ApplicationHelper
  include Pagy::Frontend
end
Identify which instance variable that handles the display of data-sets you wish to paginate. In my case, instance variables are as follows.
# app/controllers/user_controllers.rb

class UsersController < ApplicationController
  def show
    .
    .
    @friends = @user.friends
  end

  def index
    .
    .
    @nofriends = User.all_except(current_user)
  end
.
.
  def friends
    .
    @friends = @user.friends
  end
end
Edit these instance variables with Pagy attributes as below.
# app/controllers/user_controllers.rb

class UsersController < ApplicationController
  def show
    @user = User.find(params[:user_id])
    @pagy, @friends = pagy(@user.friends, items: 3) 
  end

  def index
    @users = User.all
    @pagy, @nofriends = pagy(User.all_except(current_user), page: params[:page], items: 9)
  end
.
.
  def friends
    @user = User.find(params[:user_id])
    @pagy_a, @friends = pagy_array(@user.friends, items: 9)
  end
end
On the Frontend in ERB file, add the following render for navigation link at the end of the block you want to paginate.
At the bottom of 
# app/views/users/users.html.erb

<%= pagy_bulma_nav(@pagy).html_safe %>
# app/views/micrpost/friends.html.erb

<%= pagy_bulma_nav(@pagy).html_safe %>
There are instances when the code above does not paginate array output from an instance variable. Example below shows a rails console query that has square brackets denoting as an array.
The example below shows a rails console query that is not an array. Evidently, it does not have square brackets
In my case I need to paginate array out from "
@nofriends = User.all_except(current_user), page: params[:page], items: 9
". Thankfully Pagy has a render code for arrays.
At the bottom of 
# app/views/users/friends.html.erb

<%= pagy_bulma_nav(@pagy_a).html_safe %>
After completing the steps above, refresh your rails app and try it out. Pagy is not only limited to Bulma CSS framework, but it also supports bootstrap, semantics, etc. Check out our repository to see how we've set up Pagy.
Sources here and here.

Written by gerald-goh | A Developer who finds joy in combining the appeal of design with the complexity of engineering.
Published by HackerNoon on 2020/01/08