Ruby on Rails With Endless Scrolling

Ruby on Rails with Endless Scrolling

Endless scrolling allows a website to let users avoid having to click page links or pagination in order to load additional pages of content. It is used by a number of sites such as Pinterest in order to enhanced the user experience. This article will show you how to implement endless scrolling in your Rails application. Let’s run through this with me.

Create Rails Project
To create a Rails project; open up your terminal and type commands below:

1
rails new endless_scrolling -d mysql

Setting up
Ruby on Rails endless scrolling uses the will_paginate gem to manage paging. This has a couple of advantages.

First, if your endless scrolling code doesn’t work properly or is disabled, the pagination links themselves will still be present and allow the user to page.

Second, the will_paginate gem provides us with the pagination functionality itself so that we do not need to reinvent the wheel.

To get started, add the will_paginate gem to your Gemfile file.

Gemfile
1
gem 'will_paginate', '~> 3.0.7'

Then run a bundle install to install the gem:

1
bundle install

we will create a simple Post model with the fields title, and body. In addition, we will create a simple Posts controller with an index method. Run the commands below to create these items:

1
2
3
rails g model Post title body:text
rake db:migrate
rails g controller Posts index

Then open up your routes (config/routes.rb) file and modify it so that it looks like the code listed below:

routes.rb
1
2
3
Rails.application.routes.draw do
  root to: "posts#index"
end

Then we need some seed data to play with. Open up your seeds.rb file and add in the code listed below. This code will create 100 posts for us to play with:

seeds.rb
1
2
3
4
5
(1..100).each do |i|
  Post.create!(title: "Lipsum Post #{i}", body: %{
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. In feugiat purus dapibus fermentum sagittis. Fusce in tempus felis. Phasellus a erat ut lorem lacinia bibendum. Vivamus viverra facilisis neque, in scelerisque urna pharetra vel. Donec a est mauris. Integer eget metus quis eros egestas elementum. Integer bibendum risus hendrerit dapibus tempor. Fusce placerat in orci vitae tincidunt.
  })
end

Then run rake db:seed to create the seed data:

1
rake db:seed

Then open up your Posts controller (app/controllers/posts_controller.rb) and modify it so that it looks like the code listed below:

1
2
3
4
5
class PostsController < ApplicationController
  def index
    @posts = Post.paginate(:page => params[:page], :per_page => 20)
  end
end

Now modify the index view for your Posts controller so that it looks like the code listed below.

posts_controller.rb
1
2
3
4
5
class PostsController < ApplicationController
  def index
    @posts = Post.paginate(:page => params[:page], :per_page => 20)
  end
end

Then modify the index (app/views/posts/index.html.erb) view for your Posts controller so that it looks like the code listed below:

index.html.erb
1
2
3
4
5
<div id="posts">
  <h1>Posts</h1>
  <%= render @posts %>
</div>
<%= will_paginate @posts %>

Then let’s create the post partial. Create a file called _post.html.erb (app/views/posts/_post.html.erb) for your Posts controller and add in the code listed below:

_post.html.erb
1
2
3
4
<div class="post">
  <h2><%= post.title %></h2>
  <p><%= post.body %></p>
</div>

If you were to start a rails server at this point, you’d see a typical paginated list of posts. Now it’s time to add in the javascript that will make endless scrolling work. Open up your application.js (app/assets/javascripts/application.js) file and add in the code listed below:

application.js
1
2
3
4
5
6
7
8
9
10
11
12
$(document).ready(function() {
  if ($('.pagination').length) {
    $(window).scroll(function() {
      var url = $('.pagination .next_page').attr('href');
      if (url && $(window).scrollTop() > $(document).height() - $(window).height() - 50) {
        $('.pagination').text("Please Wait...");
        return $.getScript(url);
      }
    });
    return $(window).scroll();
  }
});

Then create a file called index.js.erb (app/views/posts/index.js.erb) for your Posts controller and add in the code listed below:

index.js.erb
1
2
$('#posts').append('<%= escape_javascript render(@posts) %>');
$('.pagination').replaceWith('<%= escape_javascript will_paginate(@posts) %>');

The code works by watching the window’s scroll event. When the user scrolls past the specified threshold, more posts are loaded using AJAX. That’s it, thank you!. See ya! :)