Using will_paginate with recent changes

16 views
Skip to first unread message

Travis Reeder

unread,
Aug 4, 2009, 3:02:48 AM8/4/09
to simple...@googlegroups.com
I've replaced the regular Ruby Array response you get from Model.find() with a special array that will load more results on demand using next tokens as you iterate through them. 

But this breaks will_paginate because it's no longer a ruby core Array.

So add this to environment.rb (at the bottom) to get it to work again:


require 'will_paginate'

SimpleRecord::ResultsArray.class_eval do
  def paginate(options = {})
    raise ArgumentError, "parameter hash expected (got #{options.inspect})" unless Hash === options

    WillPaginate::Collection.create(
        options[:page] || 1,
        options[:per_page] || 30,
        options[:total_entries] || self.length
    ) { |pager|
      pager.replace self[pager.offset, pager.per_page].to_a
    }
  end
end


Chad Arimura

unread,
Sep 23, 2009, 5:05:40 AM9/23/09
to SimpleRecord

It seems that when you try to go to a page outside of the returned
result set limit, simple_record won't retrieve new records...

For example, if there are 500 total items and you're showing 50 items
per page, will_paginate properly shows the 10 page links at the
bottom, but if you click on any page above 2, the page is empty
because we've only lazily retrieved the first 100 from SDB.

Thoughts?

Travis Reeder

unread,
Sep 23, 2009, 4:04:59 PM9/23/09
to simple...@googlegroups.com
Ya, have to iterate through result sets (within SimpleRecord) to get the requested results.

Travis Reeder

unread,
Sep 24, 2009, 6:39:29 PM9/24/09
to simple...@googlegroups.com
Here's a more detailed explanation of what I mean:

SimpleRecord should handle the case where someone indexes directly into the ResultsArray, so if someone does (case 1):

my_objects = MyClass.find(:all)
x = my_objects[534]

Right now, that wouldn't work properly, it would only work if you iterated to 534 using, for instance (case 2):

x = nil
i = 0
my_objects.each do |y|
x = y
break if i == 534
i += 1
end

That would correctly give you the 534th object in the results and this is also how we'd have to handle case 1 internally since SimpleDB doesn't have any support for starting the results at a certain point. And this would obviously apply to paging, for instance (case 3):

my_page = my_objects.paginate(6, 100) # that's page 6, 100 per page

my_page would then be an array of results indexed at 500 - 599.

Internally, it would be something similar to case 2, iterating/materializing the objects up to 600, then returning the subset of 500-599.

Travis
Reply all
Reply to author
Forward
0 new messages