lib/will_paginate/collection.rb in will_paginate-2.3.17 vs lib/will_paginate/collection.rb in will_paginate-3.0.pre
- old
+ new
@@ -1,7 +1,5 @@
-require 'will_paginate/per_page'
-
module WillPaginate
# = Invalid page number error
# This is an ArgumentError raised in case a page was requested that is either
# zero or negative number. You should decide how do deal with such errors in
# the controller.
@@ -17,29 +15,13 @@
#
# This error is *not* raised when a page further than the last page is
# requested. Use <tt>WillPaginate::Collection#out_of_bounds?</tt> method to
# check for those cases and manually deal with them as you see fit.
class InvalidPage < ArgumentError
- # a value bigger than this would result in invalid SQL queries
- BIGINT = 9223372036854775807
-
- def self.validate(page_value, per_page_value)
- page = page_value.to_i
- raise self.new(page_value, page) if page < 1
- per_page = per_page_value.to_i
- offset = (page - 1) * per_page
- raise self, "invalid offset: #{offset.inspect}" if offset < 0 or offset > BIGINT
- [page, per_page]
+ def initialize(page, page_num) #:nodoc:
+ super "#{page.inspect} given as value, which translates to '#{page_num}' as page number"
end
-
- def initialize(value, page_num = nil)
- if page_num
- super "#{value.inspect} given as value, which translates to '#{page_num}' as page number"
- else
- super value
- end
- end
end
# = The key to pagination
# Arrays returned from paginating finds are, in fact, instances of this little
# class. You may think of WillPaginate::Collection as an ordinary array with
@@ -49,23 +31,29 @@
# WillPaginate::Collection also assists in rolling out your own pagination
# solutions: see +create+.
#
# If you are writing a library that provides a collection which you would like
# to conform to this API, you don't have to copy these methods over; simply
- # make your plugin/gem dependant on this library and do:
+ # make your plugin/gem dependant on the "will_paginate" gem:
#
+ # gem 'will_paginate'
# require 'will_paginate/collection'
- # # WillPaginate::Collection is now available for use
+ #
+ # # now use WillPaginate::Collection directly or subclass it
class Collection < Array
attr_reader :current_page, :per_page, :total_entries, :total_pages
# 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.
- def initialize(page, per_page = WillPaginate.per_page, total = nil)
- @current_page, @per_page = InvalidPage.validate(page, per_page)
+ 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
# Just like +new+, but yields the object after instantiation and returns it
# afterwards. This is very useful for manual pagination:
@@ -92,11 +80,11 @@
# end
# end
#
# The Array#paginate API has since then changed, but this still serves as a
# fine example of WillPaginate::Collection usage.
- def self.create(page, per_page, total = nil)
+ def self.create(page, per_page, total = nil, &block)
pager = new(page, per_page, total)
yield pager
pager
end
@@ -108,11 +96,11 @@
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
- # side by side with records in the view: simply start with offset + 1.
+ # besides your records: simply start with offset + 1.
def offset
(current_page - 1) * per_page
end
# current_page - 1 or nil if there is no previous page
@@ -122,11 +110,10 @@
# current_page + 1 or nil if there is no next page
def next_page
current_page < total_pages ? (current_page + 1) : nil
end
-
- # sets the <tt>total_entries</tt> property and calculates <tt>total_pages</tt>
+
def total_entries=(number)
@total_entries = number.to_i
@total_pages = (@total_entries / per_page.to_f).ceil
end