module SimplePagination
class PageCollection
##
# Create a new PageCollection object. The following options are available.
# [:current_offset] The zero-based offset of the first record in the current page of results
# [:current_page] The one-based offset of the current page of results (alternative to :current_offset)
# [:total_records] The total number of results across all pages
# [:total_pages] The total number of pages (alternative to :total_records)
# [:page_size] The page size
#
# You can choose between :current_offset and :current_page based on your
# needs. Same goes for :total_records and :total_pages. :page_size
# is required.
#
# A typical use of this class would be to define a pages method on your
# result set class which returns an instance of PageCollection. (So you can
# do, e.g., my_result_set.pages.current and so on.)
def initialize(options={})
check_options(options)
@pages, @page_size = {}, options[:page_size]
@length = options[:total_pages] || (options[:total_records] / @page_size.to_f).ceil
@current_page = options[:current_page] || (options[:current_offset]/@page_size)+1
end
##
# A Page object representing the page at a given page number (one-based).
def [](i)
@pages[i] ||= Page.new(i, self) unless out_of_bounds?(i)
end
##
# A Page object representing the current page in the collection.
def current
self[@current_page]
end
##
# A Page object representing the first page in the collection.
def first
self[1]
end
##
# A Page object representing the last page in the collection.
def last
self[length]
end
##
# The number of pages in the collection.
attr_reader :length
##
# The number of records shown on each page in the collection.
attr_reader :page_size
private
def check_options(options)
raise ArgumentError, "requires :current_offset or :current_page" unless options[:current_offset] || options[:current_page]
raise ArgumentError, "requires :page_size" unless options[:page_size]
raise ArgumentError, "requires :total_pages or :total_records" unless options[:total_pages] or options[:total_records]
end
def out_of_bounds?(i)
i > length || i < 1
end
end
end