Skip to content

Instantly share code, notes, and snippets.

@rondy
Created October 26, 2011 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rondy/1317864 to your computer and use it in GitHub Desktop.
Save rondy/1317864 to your computer and use it in GitHub Desktop.
Paginator for Enumerable
class Paginator
DEFAULT_PAGE = 1
DEFAULT_PER_PAGE = 5
attr_reader :page
attr_reader :per_page
def paginate(collection, options={})
setup(options)
slice(collection)
end
private
def setup(options={})
@page, @per_page = fetch_options(options)
end
def fetch_options(options={})
_options = default_options.merge(options) do |key, oldval, newval|
(newval < 0) ? oldval : newval
end
[_options[:page], _options[:per_page]]
end
def default_options
@default_options ||= {
:page => DEFAULT_PAGE,
:per_page => DEFAULT_PER_PAGE
}
end
def slice(collection)
collection[head..tail] if collection.kind_of?(Enumerable)
end
def head
offset - per_page
end
def tail
offset - 1
end
def offset
page * per_page
end
end
module Enumerable
def paginate(options={})
Paginator.new.paginate(self, options)
end
end
letters = ("a".."z").map { |letter| letter }
puts letters.paginate.inspect # => ["a", "b", "c", "d", "e"]
puts letters.paginate(:page => 2).inspect # => ["f", "g", "h", "i", "j"]
puts letters.paginate(:per_page => 3).inspect # => ["a", "b", "c"]
puts letters.paginate(:page => 2, :per_page => 3).inspect # => ["d", "e", "f"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment