Infinite Scroll Pagination in Ruby on Rails apps

Infinite Scroll Pagination in Ruby on Rails apps

A tutorial on how to achieve infinite scroll in Ruby on Rails apps

2022-11-10T00:00:00.000Z


The Problem

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.

Untitled

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.

Get started

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.

Untitled

PS: Remember to restart your server, I had errors until I restarted the server.

Untitled

In your posts_controller.rb, include Pagy.

Untitled

In your Index method, set up Pagy’s Countless subclass.

Untitled

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:

Untitled

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.

Untitled

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.

Untitled

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: @pagy.next 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.

Untitled

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.