Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Paginate an already-fetched result set (i.e. collection or array) (See related posts)

Sometimes it's nearly impossible to paginate a result set using the built-in :limit and :offset parameters of find(:all). Instead, you can fetch a complicated query and paginate the results afterward.

Add the following to application.rb:

  def paginate_collection(collection, options = {})
    default_options = {:per_page => 10, :page => 1}
    options = default_options.merge options
    
    pages = Paginator.new self, collection.size, options[:per_page], options[:page]
    first = pages.current.offset
    last = [first + options[:per_page], collection.size].min
    slice = collection[first...last]
    return [pages, slice]
  end


Call it from within your action like this:
@pages, @users = paginate_collection User.find_custom_query, :page => @params[:page]

Comments on this post

remvee posts on Jul 14, 2005 at 08:55
Thanks, that's very useful! Can you please put a "rails" and "ruby" tag on it?
peter posts on Jul 21, 2005 at 23:22
Done.
dpunk posts on Aug 19, 2005 at 15:44
Is there a performance issue with getting a potentially large result set and then paginating afterwards? Or is it fine because the results are stored into memory (in a fcgi environment?)?? Thanks.
toolmantim posts on Nov 08, 2005 at 03:24
A modification on the above that allows block syntax (which can eliminate a temp in most cases)

    # Paginates an existing AR result set, returning the Paginator and collection slice.
    #
    # Based upon:
    # http://www.bigbold.com/snippets/posts/show/389
    #
    # Options:
    # +:collection+: the collection to paginate
    # +:per_page+: records per page
    # +:page+: page
    #
    # Example:
    #   complex_query_result = Customer.find_by_sql('something complex')
    #   @pages, @customers = paginate_collection(:collection => complex_query_result)
    # 
    # Alternatively, you can specify a block, the result of which will be used as the collection:
    #   @pages, @customers = paginate_collection { Customer.find_by_sql('something complex') }
    def paginate_collection(options = {}, &block)
      if block_given?
        options[:collection] = block.call
      elsif !options.include?(:collection)
        raise ArgumentError, 'You must pass a collection in the options or using a block'
      end
      
      default_options = {:per_page => 10, :page => 1}
      options = default_options.merge options

      pages = Paginator.new self, options[:collection].size, options[:per_page], options[:page]
      first = pages.current.offset
      last = [first + options[:per_page], options[:collection].size].min
      slice = options[:collection][first...last]
      return [pages, slice]
    end
canadaduane posts on Jan 27, 2006 at 21:58
There's definitely a performance hit. You only want to do this kind of pagination when you're sure the result set won't become crazy huge. I suspect we'll be seeing some much better pagination support in the Rails core soon (or at least via plugins).
altano posts on Feb 02, 2006 at 15:27
I added this:
options[:page] = options[:page] || params[:page] || 1

so that I don't need to specify :page => @params[:page] all the time. It looks like this now:

	def paginate_collection(collection, options = {})
		options[:page] = options[:page] || params[:page] || 1
		
		default_options = {:per_page => 10}
		options = default_options.merge options
guptanehas posts on Sep 19, 2006 at 06:40
hi actually i needed some help.
i ve made a search engine for some xyz website..
now i need 2 paginate the resultanat variable.
say @programme variable.
It contains my search result n i need 2 paginate @programme variable.

but since the search engine doesnt ve any resp. model it has only controller i m unable to use either paginate helper or paginate by sql for the same.
kindly guide me as on how to paginate a particular variable.

Thanx n Regards,

Neha Gupta
viggo posts on Oct 30, 2007 at 08:05
Thanks, works fine for me. :)

You need to create an account or log in to post comments to this site.


Click here to browse all 5140 code snippets

Related Posts