Infinite Scroll Pagination in Ruby on Rails apps

Published 08 April 2022

Infinite Scroll Pagination in Ruby on Rails apps Cover Image

Infinite Scroll Pagination in Ruby on Rails apps

In my PM roadmap, I had some minor improvements for the scrolling of users in Kubukisa, one of my passion projects. Below is how I had it initially using the pagy gem

Kubukisa pagination example

Not really the best-looking pagination if you are a perfectionist like me. I mean, it can do but why not improve it, right?! For the purposes of this article, I will use my personal site for reference, particularly, the POST resource on how to go about implementing infinite scrolling. 

To get started, you need to install Hotwire Turbo in your app. For Rails apps, you need the gem, this will be important as we’ll be using turbo_streams. Next, you will need to include the Pagy Countless subclass which is useful for saving one count query per request, this will be important later in the implementation.
Require in Pagy
PS: Remember to restart your server, I had errors until I restarted the server.
Example error
In your posts_controller.rb, include Pagy.
PostsController example
In your Index method, set up Pagy’s Countless subclass.
PostsController Example

You don’t need the WHERE clause if you don’t have conditions you would like to set for your resources. You will also need to explicitly indicate the formats the index view will respond to. You will later see how to set these up. The respond_to block is a helper method on the superclass PostsController that takes |format| as the argument to the block. This Rails helper method references the response that will be sent to the View (i.e. on the browser).

From here, in your views, particularly, the index view, declutter your view and use partials as below:
Posts show view

I use Tailwind CSS for my projects, in case you use Bootstrap, etc. you can discard my classes. What is most important here is including the id of posts (highlighted above) which is what turbo will be used to reference the posts on each query.

Back in the index view, you need to set up the rendering of the above partial view (you can read more on partials here) as well as the turbo_stream_tag helper to create a turbo stream.
Index view

Here, you will notice that the div wrapping the posts partial has an id which is important. This id is named according to your resource, e.g. articles or towns. The turbo_frame_tag is lady loaded and most importantly, pulls the queries from the posts_path and displays the queries in the turbo_stream format we defined on the posts_controller respond_to helper method.

I hope you are still following and everything is starting to come together. 

We further will need to create the index.turbo_stream.erb view for turbo.
Index turbo stream
Here, we have to wrap the posts partial in a turbo_stream and append it with the posts resource. The turbo_frame_tag is similar to that in the index.html.erb and does the same thing. To prevent the loading to be infinitely looped, you will have to include page: which checks the size of the paginated collection (@records) in order to know if it is the last page or not.

There you have it, you now have infinite scrolling.
pagination_final copy.mp4
How would you better optimize this feature? @ mention me on Twitter (@ThubaMamba) or LinkedIn (@thubamamba) and let’s keep the conversation going. Keep building and shipping cool stuff. 


Rails, Stimulus JS