resourceful_pagination

Posted on 03 Aug 2008

I've been doing quite a bit of work recently on an Active Resource project and needed to add pagination to one of our resources. I had a quick look around to see what other people were doing, and while it looks like work is underway to add support for Active Resource (and ORMs other than Active Record) to will_paginate I don't think it's quite ready just yet. So while we wait, may I present resourceful_pagination.

If you want to dive straight in, take a look at the readme then install the gem with:

sudo gem install phorsfall-resourceful_pagination --source http://gems.github.com

With the gem installed you get a shiny new ActiveResource::Base#paginate method. Use it like this:

MyResource.paginate(:page => params[:page])

This returns a WillPaginate::Collection which you can use with will_paginate's view helpers as usual.

Easy, right?, Well, sort of. The gem makes a few assumptions about your Active Resource class and your RESTful resource. If you want to use this you'll probably need to make a few changes. First you need to add two class methods to your Active Resources.

  1. A count method which returns the total number of items. This could call a custom count action on the app server.
  2. A per_page method indicating how many records you require per page.

Something like this would do the trick:

class MyResource < ActiveResource::Base
  @@per_page = 10
  cattr_reader :per_page

  def self.count
    get(:count)['count']
  end
end

You also need the index action of the controller on the app server to handle the :starting_at and :per_page parameters. These map to :offset and :limit in SQL and can be passed straight through to Active Record.

MyResourcesController < ApplicationController
  def index
    MyResource.find :all, :limit => params[:per_page], :offset => params[:starting_at]
    # Render XML etc.
  end

  def count
    count = MyResource.count
    render :xml => { :count => count }
  end
end

And that's about it. There's a little bit more to do if you have a nested resource, but there's a bit more on that in the readme.

Enjoy.