Translations of this page?:

Pagination with WillPaginate

It is a frequent requirement that your Rails views not display all of the records in an array on one page. In those cases, you need to implement pagination. That functionality is made simple with the use of the WillPaginate gem.

NOTE: WillPaginate requires that your Ruby gems be at least v.1.2.

(Most of this information comes from the WillPaginate documentation.)

Installation

The WillPaginate gem is built by GitHub. Add GitHub to your gem sources (once per machine):

$ gem sources -a http://gems.github.com

You don't need to do this with updated rubygems (1.6 or greater) as both will_paginate and rubygems have moved to gemcutter hosting.

Install the library:

$ gem install mislav-will_paginate

Requiring the Gem

Rails 2.0.x or earlier

To enable the library simply load it in “config/environment.rb”

Rails::Initializer.run do |config|
  ...
end
 
require "will_paginate" 

Don't put it before or inside the Rails::Initializer block because the Rails framework is not yet loaded at that point of execution.

Rails 2.1 or newer

You will want to use use Gem dependencies to load the will_paginate gem. Simply add the following code to config/environment.rb:

Rails::Initializer.run do |config|
...
  config.gem 'mislav-will_paginate', 
    :lib => 'will_paginate', 
    :source => 'http://gems.github.com'
...
end

Example Usage

Use a paginate finder in the controller:

page = params[:page] || 1
@posts = Post.paginate_by_board_id @board.id, :page => page, :order => 'updated_at DESC'

Paginate works just like find — it just doesn't fetch all the records. Don't forget to tell it which page you want, or it will complain! Read more on WillPaginate::Finder::ClassMethods.

Render the posts in your view like you would normally do. When you need to render pagination, just stick this in:

<%= will_paginate @posts %>

Will_paginate determines how many records to display per page by calling the per_page class method for the model being returned by the query. You can define the per_page method like this:

class Post < ActiveRecord::Base
  cattr_reader :per_page
  @@per_page = 50
end

… or like this:

class Post < ActiveRecord::Base
  def self.per_page
    50
  end
end

If your class doesn't specify, the default :per_page value is 30. You can also always specify this value explicitly in your controller:

@posts = Post.paginate :page => params[:page] || 1, :per_page => 50

The paginate finder wraps the original finder and returns a collection that has some extra properties. You can use the returned collection as you would with any ActiveRecord result set. WillPaginate view helpers also need that object to be able to render pagination:

<ol>
  <% @posts.each do |post|  -%>
    <li><%= link_to post.title, post %></li>
  <% end -%>
</ol>

Additional Documentation

 
howtos/pagination.txt · Last modified: 2010/03/18 02:37 by bluehavana
 
Recent changes RSS feed Creative Commons License