ActiveResource pagination
I didn’t find any good article on how to do pagination on ActiveResource, so here’s my 2ยข. Basically, I wanted to do as less changes to the server as possible. As we already using pagination on the server side, the only change was to add info about total number of items and items per page to the server’s xml response. This is needed by client to properly build pagination links inside it’s view.
Server controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def index @airports = Airport.paginate(:page => params[:page], :per_page => APP_CONFIG['airports_per_page']) respond_to do |format| format.html # index.html.erb format.xml { @airports << { :pagination_members_total => @airports.total_entries, :pagination_members_per_page => APP_CONFIG['airports_per_page'] } render :xml => @airports } end end |
There’s no pagination done at the client side, we just need to extract the pagination parameters and pass them to will_paginate view helper.
Client controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
def index current_page = params[:page] || 1 total_members, per_page = 0 airports = Airport.find(:all, :params => { :page => current_page}) airports.each_index{|x| if airports[x].respond_to?(:pagination_members_total) && airports[x].respond_to?(:pagination_members_per_page) total_members = airports[x].pagination_members_total per_page = airports[x].pagination_members_per_page airports.delete_at x break end } @airports = WillPaginate::Collection.create(current_page, per_page, total_members) do |pager| pager.replace airports end end |
Client view (same as on server)
1 2 |
<%= will_paginate @airports %>
|
Looks a bit ugly, but works. Please let me know if there’s a better solution.
February 15, 2012 at 4:18 PM
I realized that it can be done with additional server headers.
Look here https://github.com/Fivell/activeresource-response
October 22, 2011 at 8:00 AM
I had a dream to start my own business, however I did not earn enough amount of money to do this. Thank goodness my colleague advised to take the <a href="http://goodfinance-blog.com/topics/home-loans">home loans</a>. Thus I took the short term loan and realized my old dream.
February 14, 2010 at 5:48 PM
PoxPaginate should take care of this. http://github.com/c42/pox_paginate
October 12, 2009 at 9:43 PM
Awesome! I've wrapped this solution into a separate file. require it in your environment.rb file and you should be able to call...
AnyActiveResource.paginate ... in your client
and
AnyActiveRecord.paginate_for_remote ... in your server
Doesn't really improve on the code just moves the ugliness out of the controllers. :-)
class ActiveResource::Base def self.paginate(*args) total_members, per_page = 0 options = args.detect{|a| a.is_a?(Hash) && a.has_key?(:params)} if options params = options[:params] else return end current_page = params[:page] || 1 params[:per_page] ||= 30 rs = find(*args) if rs[0].respond_to?(:pagination_members_total) && rs[0].respond_to?(:pagination_members_per_page) total_members = rs[0].pagination_members_total per_page = rs[0].pagination_members_per_page rs.delete_at 0 end WillPaginate::Collection.create(current_page, per_page, total_members) do |pager| pager.replace rs end end end class ActiveRecord::Base def self.paginate_for_remote(*args) params = args.detect{|a| a.is_a?(Hash) && a.has_key?(:per_page)} if params per_page = params[:per_page] else return end rs = paginate(*args) rs = [{:pagination_members_total => rs.total_entries, :pagination_members_per_page => per_page}] + rs end endMay 14, 2009 at 9:23 PM
@airports = [{
:pagination_members_total => @airports.total_entries,
:pagination_members_per_page => APP_CONFIG['airports_per_page']
}] + @airports
Then
if airports[0].respond_to?(:pagination_members_total) && airports[0].respond_to?(:pagination_members_per_page)
total_members = airports[0].pagination_members_total
per_page = airports[0].pagination_members_per_page
airports.delete_at 0
Thanks for the help too....
March 20, 2009 at 9:41 AM
Thanks a million for this!