Mar 03

Date published: 3-3-2014

Rails version: 4.0.0

Pagination

It’s common on web sites to have large numbers of records in the database. It’s not always useful to see all the items in the database at the same time as it could take a long time to load and involve a lot of scrolling to find the information we want. This is where pagination can be used as a helpful way to divide a set of results into chunks that are easier to use. A good example of pagination that is familiar to any web user is the set of links at the bottom of the page of search engines like Google. It has links to go to the next and previous pages and information about how many pages there are to look through.

Copy the template site

The first thing we need to do is copy our template site and create a new project from it. Open a terminal window and switch to the directory where the template Bootstrap site is located. Run the following commands:

$ cp -r template_bootstrap_site/ pagination_tutorial
$ cd pagination_tutorial/

It’s a good idea now to change the module name just like we did in this tutorial in the section titled, “Update the module information.” Make sure to commit your changes to Git before moving on.

Create a Post model and views

We want to learn about pagination, but first we need a basic model to store information in the database. We’ll let Rails handle that for us as we don’t want to spend a lot of time creating views we won’t be using much. Switch to the terminal window and run the following:

$ rails generate scaffold Post title:string
$ rake db:migrate
==  CreatePosts: migrating ====================================================
-- create_table(:posts)
   -> 0.0021s
==  CreatePosts: migrated (0.0022s) ===========================================

With those commands, we created a Post model with all the views it needs and setup the database. Let’s modify the root path in app/config.rb to point to the index of posts:

root 'posts#index'

Start the Rails server, and you’ll see that we have some basic pages there to show the titles of our posts. We can make new posts, but it would take a long time to enter a bunch of new posts manually. Let’s use the Rails console to quickly add a large number of entries in the database. In the terminal window, run these commands:

$ rails c
Loading development environment (Rails 4.0.0)
2.0.0-p195 :001 > 100.times do |n|
2.0.0-p195 :002 >     post = Post.new
2.0.0-p195 :003?>   post.title = "Post #{n}"
2.0.0-p195 :004?>   post.save
2.0.0-p195 :005?>   end
2.0.0-p195 :006 > Post.all.size
   (0.3ms)  SELECT COUNT(*) FROM "posts"
 => 100
2.0.0-p195 :007 > exit

Now if you reload the index page, you’ll see that there are a hundred new posts in our list. We’ve got everything we need setup now to add pagination, so let’s save our changes in Git:

$ git add .
$ git commit -m "Create Post model and views"

Adding pagination

Adding pagination is fairly simple. The template site already has the two gems loaded in the Gemfile:

gem 'will_paginate', '3.0.4'
gem 'bootstrap-will_paginate', '0.0.9'

We need to change the controller as we need to know what page we’re on to fetch the correct records from the database. Modify the index action in app/controllers/posts_controller.rb:

  def index
    @posts = Post.paginate(page: params[:page])
  end

If you reload the page, you’ll see that now only thirty items are being loaded on the page. We need to show the links at the bottom of the list so the user can switch to the next page or select the number of the page they want to view. Add the following line after the table showing the posts in app/views/posts/index.html.erb:

<%= will_paginate @posts %>

Reload the page, and you’ll find the links at the end of the list. Play around with selecting Next, Previous, and the number of the page you want to view, and you’ll see it loads in thirty records at a time. If we want to change the number of records being shown, we can do that by slightly changing our call to paginate in the controller. Change the controller to look like:

@posts = Post.paginate(page: params[:page], per_page: 10)

Now if you load the page, it will load in ten records at a time. You can change the number to whatever value you want to load in as few or as many records as you desire. That’s all we need to add for pagination, so let’s save the changes in Git:

$ git add .
$ git commit -m "Added pagination to Posts"

The source code for this tutorial can be found at:

http://github.com/wordplay/pagination_tutorial

Leave a Reply

preload preload preload