class Leaf::Collection
The key to pagination¶ ↑
Arrays returned from paginating finds are, in fact, instances of this little class. You may think of Leaf::Collection
as an ordinary array with some extra properties. Those properties are used by view helpers to generate correct page links.
gem 'leaf' require 'leaf/collection' # now use Leaf::Collection directly or subclass it
Attributes
Public Class Methods
Just like new
, but yields the object after instantiation and returns it afterwards. This is very useful for manual pagination:
# File lib/leaf/collection.rb, line 40 def self.create(page, per_page, total = nil, &block) pager = new(page, per_page, total) yield pager pager end
Arguments to the constructor are the current page number, per-page limit and the total number of entries. The last argument is optional because it is best to do lazy counting; in other words, count conditionally after populating the collection using the replace
method.
# File lib/leaf/collection.rb, line 29 def initialize(page, per_page, total = nil) @current_page = page.to_i raise InvalidPage.new(page, @current_page) if @current_page < 1 @per_page = per_page.to_i raise ArgumentError, "`per_page` setting cannot be less than 1 (#{@per_page} given)" if @per_page < 1 self.total_entries = total if total end
Public Instance Methods
current_page
+ 1 or nil if there is no next page
# File lib/leaf/collection.rb, line 67 def next_page current_page < total_pages ? (current_page + 1) : nil end
Current offset of the paginated collection. If we're on the first page, it is always 0. If we're on the 2nd page and there are 30 entries per page, the offset is 30. This property is useful if you want to render ordinals besides your records: simply start with offset + 1.
# File lib/leaf/collection.rb, line 57 def offset (current_page - 1) * per_page end
Helper method that is true when someone tries to fetch a page with a larger number than the last page. Can be used in combination with flashes and redirecting.
# File lib/leaf/collection.rb, line 49 def out_of_bounds? current_page > total_pages end
current_page
- 1 or nil if there is no previous page
# File lib/leaf/collection.rb, line 62 def previous_page current_page > 1 ? (current_page - 1) : nil end
This is a magic wrapper for the original Array#replace method. It serves for populating the paginated collection after initialization.
Why magic? Because it tries to guess the total number of entries judging by the size of given array. If it is shorter than per_page
limit, then we know we're on the last page. This trick is very useful for avoiding unnecessary hits to the database to do the counting after we fetched the data for the current page.
However, after using replace
you should always test the value of total_entries
and set it to a proper value if it's nil
. See the example in create
.
# File lib/leaf/collection.rb, line 88 def replace(array) result = super # The collection is shorter then page limit? Rejoice, because # then we know that we are on the last page! if total_entries.nil? and length < per_page and (current_page == 1 or length > 0) self.total_entries = offset + length end result end
# File lib/leaf/collection.rb, line 71 def total_entries=(number) @total_entries = number.to_i @total_pages = (@total_entries / per_page.to_f).ceil end