Recently I needed to add infinite scroll to a list view on a Rails app I’m working on. It turned out to be pretty straightforward, so here are the steps I took to get it working.

This tutorial assumes use of a default Rails 5.1.4 installation, with the addition of haml and jquery-rails. This means Sprockets, coffee, and turbolinks are in use. However most of the following code is trivial to convert if you aren’t using these helpers. I’m also referencing a Post model, but again, if you’re using a different class all you need to do is replace any reference to Post with your class.

You can view a demo app made using this tutorial here, and you can also clone it on github.

First you’ll need to add the will_paginate gem to your gemfile, and include the jquery.inview plugin (put this in the vendor/assets/javascripts folder).

Gemfile

application.js

After that, add a per_page parameter to your model. For example, in post.rb:

Then, in your controller, replace the query with a paginated query, and add format.js to the format response. I’ve included an example showing how to add pagination to the index view, and also how to add it to a scoped query. For example, in posts_controller.rb:

You’ll need a partial that renders your items. For simplicity, I’ve created a shared partial called _posts.html.haml in the shared folder:

Edit your template and add a Load More link. For example, in index.html.haml. We’ve included a test to see if there actually is a next page of content, if not – don’t display the Load More link.

Then create your js template, index.js.haml. Notice that the same next_page method is called on the posts to hide the Load More link when there’s no more content.

And finally add the javascript to load posts automatically when the Load More link is in view, in posts.coffee

And you’ll be good to go! This is all you need to do to add pagination with infinite scroll. If you have any problems, check the demo app and see if you can find any differences.

If this post has helped you out, feel free to consider throwing a small donation my way.