DZone 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)
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
Snippets Manager replied on Tue, 2007/10/30 - 6:46am
Snippets Manager replied on Tue, 2006/09/19 - 6:34am
Snippets Manager replied on Thu, 2006/02/02 - 4:07pm
options[:page] = options[:page] || params[:page] || 1so 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 optionsSnippets Manager replied on Mon, 2012/05/07 - 2:12pm
Snippets Manager replied on Mon, 2012/05/07 - 2:12pm
# 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] endSnippets Manager replied on Mon, 2012/05/07 - 2:12pm
Snippets Manager replied on Mon, 2012/05/07 - 2:12pm
Snippets Manager replied on Mon, 2012/05/07 - 2:12pm