will_paginate is very well designed plugin. Besides ActiveRecord object integration, it can integrate with array and any collection that you may have. The README.rdoc (in version 2.2.2) and wiki clearly and concisely document how to use it with ActiveRecord objects. I recently needed to use it for a collection outside of activerecord and here is how I did it.
My input params supplied the current page and the per_page. So, I had
current_page = params[:page]
per_page = params[:per_page] # could be configurable or fixed in your app
1) Fetch your collection:
In case of ActiveRecord object, we would do:
@posts = Post.paginate :page => params[:page], :per_page => 50
In case of non-ActiveRecord, the onus is still on us to fetch just the records that we need. If we can’t and we need to work with full collection, will_paginate doesn’t mind. So, here we go…
# Non-ActiveRecord Post
@posts = Post.perform_search_and_obtain_collection(params[:criteria])
2) IMP*: Create an instance of WillPaginate::Collection class.
@page_results = WillPaginate::Collection.create(current_page, per_page, @results.total_results) do |pager|
pager.replace(@posts.to_array)
end
WillPaginate::Collection extends Array class and added properties like @current_page, @per_page, @total_entries etc. We pass the current_page, per_page properties in constructor and we replace the array contents by converting our @posts to an array (@posts.to_array). This is assuming that @posts contains only the collection for current-page. If @post contains _all_ results, then we can do following:
@page_results = WillPaginate::Collection.create(current_page, per_page, @results.total_results) do |pager|
start = (current_page-1)*per_page # assuming current_page is 1 based.
pager.replace(@posts.to_array[start, per_page])
end
If our search results were already an array, then it is even easier. All we do is:
@page_results = @posts.paginate(params[:current_page], params[:per_page])
Yes, the plugin adds a method “paginate” to Array class.
Once we have an instance of WillPaginate::Collection object, it behaves exactly same as the one we normally obtain from ActiveRecord.paginate() function. So, we can continue to do this in viewer:
<ol> <% for post in @page_results -%> <li>Render `results` in some nice way.</li> <% end -%> </ol> <p>Now let's render us some pagination!</p> <%= will_paginate @page_results %>
Also, I encourage you to peek into the source code. I found paginated_section that renders pagination stuff at the top/bottom of page.
<% paginated_section @posts do %> <ol id="posts"> <% for post in @posts %> <li> ... </li> <% end %> </ol> <% end %>
Even the rendering is done using a pluggable class, incase if you want to render page links differently.
Related Services: Ruby on Rails Development, Custom Software Development

Thanks this is exactly what I need.
Thank you so much. I googled for a whole day, and eventually I found your post. And your method solved all the problems I need to tack! Cheer!
Yeah I looked for hours before finding this. And it was just what I needed. Thanks alot
Am I the only one getting the exception: Wrong number of arguments (2 for 1) trying this:
@page_results = @posts.paginate(params[:current_page], params[:per_page])
Thanks!
Found it:
http://mislav.uniqpath.com/static/will_paginate/doc/
2.2.0, released 2008-04-07 API changes
Remove old, deprecated style of calling Array#paginate as “paginate(page, per_page)”.
If you want to specify :page, :per_page or :total_entries, use a parameter hash.
hey guys, nice post. i using rails to build a client which only consumes restful webservice with activeresource, so i deactivated activerecord. i’m getting an array of activeresource object limited by :page and :per_page an so on. if i try to call will_paginate @results in the view it gives me an NoMethodError. In the controller i’m using that WillPaginate::Collection.create(…) and it doesn’t complain. but if i activate activerecord everything works. how can i say will_paginate not to be dependent on activerecord
do i really have to patch it myself?
Thanks works like a charm. I used the way you describe here
I can’t figure out how to use the pagination with an existing array of objects got from has_many associations. So, I have Enterprise model and Service model. Enterprise has_many :services. I’d like to show services for every enterprise; In my ServicesController in index action I do:
before_filter : find_client
def index
@services = @client.services
end
private
rder => ‘created_at’, :per_page => 20
def find_client
@client = Client.find(:client_id)
end
How is it possible? If try to use like that:
@services = @client.services.paginate :page => params[:page],
I get:
NoMethodError in Enterprises#show
Showing app/views/enterprises/show.html.erb where line #21 raised:
undefined method `total_pages’ for #
Extracted source (around line #21):
18: “/services/service”,
19: :collection => @enterprise.services, :locals=> {:client => @enterprise} %>
20:
21:
22:
23:
24: |
Nice post! I would like to run the search query to multiple models. What I understand from this post, for each model I should create a method that do the research and return it as an array. And then collect the two arrays from the models and then paginate. This means the sql query is executed for every pagination. What if the query result is huge? What is the best way to do this?
Thanks!
u r The man. Thank you so much!
Thanks. Very helpful to me.
Thanks for this! Honestly didn’t know that will_paginate added a ‘paginate’ method to Array. Cheers.
Great post. I should have looked at the comments sooner, as I spent a bit of time before realizing that the paginate method, when called from an array, needs the params specified in a hash.