class Datmachine::Pager

Constants

DEFAULT_LIMIT
DEFAULT_SEP

Attributes

href[RW]
options[RW]

Public Class Methods

new(href, options = {}) click to toggle source

A pager for paginating through resource records.

@param [String] uri the uri of the resource @param [Hash] options @option options [Integer] limit @option options [Integer] offset @option options [Integer] per an alias for the :limit option

# File lib/datmachine/pager.rb, line 20
def initialize(href, options = {})
  @href = href
  @options = options
  @page = nil
  @resource_class = nil
end

Public Instance Methods

all(options = {}) click to toggle source
# File lib/datmachine/pager.rb, line 157
def all(options = {})
  paginate(options).to_a
end
create(options={}) click to toggle source
# File lib/datmachine/pager.rb, line 170
def create(options={})
  opts = Datmachine::Utils.indifferent_read_access options
  opts[:href] = @href
  # if we don't have a media type for the href,
  # let's try to inspect the url to look it up from the
  # registry
  if @resource_class.nil?
    @resource_class = Datmachine.from_href(@href)
  end
  @resource_class.new(opts).save
end
current_page() click to toggle source
# File lib/datmachine/pager.rb, line 73
def current_page
  (offset / limit) + 1
end
each() { |construct_from_response| ... } click to toggle source

@return [Array] Iterates through the current page of records. @yield [record]

# File lib/datmachine/pager.rb, line 85
def each
  return enum_for :each unless block_given?

  load! unless @page
  loop do
    items.each do |r|
      envelope = {
        :meta => @page[:meta],
        :links => @page[:links],
        @resource_class.collection_name.to_sym => [r]
      }
      yield resource_class.construct_from_response(envelope)
    end
    raise StopIteration if @page[:meta].nil?
    #raise StopIteration if @page[:meta][:next].nil?
    self.next
  end
end
fetch(uri) click to toggle source
# File lib/datmachine/pager.rb, line 161
def fetch(uri)
  if resource_class.respond_to? :find
    raise NoMethodError,
        "#find must be called on #{resource_class} directly"
  end

  resource_class.fetch uri
end
fetch_each() { |record| ... } click to toggle source

@return [nil] @see Resource.fetch_each @yield [record]

# File lib/datmachine/pager.rb, line 107
def fetch_each
  return enum_for :fetch_each unless block_given?
  begin
    each { |record| yield record }
  end while self.next
end
first() click to toggle source
# File lib/datmachine/pager.rb, line 33
def first
  load! unless @page
  if items.first.nil?
    nil
  else
    envelope = {
      :meta => @page[:meta],
      :links => @page[:links],
      @resource_class.collection_name.to_sym => [items.first]
    }
    resource_class.construct_from_response(envelope)
  end
end
items() click to toggle source
# File lib/datmachine/pager.rb, line 64
def items
  load! unless @page
  if @resource_class.nil?
    []
  else
    @page[@resource_class.collection_name]
  end
end
limit() click to toggle source
# File lib/datmachine/pager.rb, line 52
def limit
  load! unless @page
  @page[:meta][:limit]
end
Also aliased as: limit_value
limit_value()
Alias for: limit
load!() click to toggle source

@return [Array, nil] Load (or reload) the pager’s collection from the original, supplied options.

# File lib/datmachine/pager.rb, line 140
def load!
  load_from @href, @options
end
Also aliased as: reload
next() click to toggle source

@return [Array, nil] Refreshes the pager’s collection of records with the next page.

# File lib/datmachine/pager.rb, line 116
def next
  load! unless @page
  next_uri = @page[:meta][:next]
  load_from next_uri, nil unless next_uri.nil?
end
num_pages() click to toggle source
# File lib/datmachine/pager.rb, line 77
def num_pages
  num = total / limit
  num += 1 if total % limit > 0
  num
end
offset() click to toggle source
# File lib/datmachine/pager.rb, line 58
def offset
  load! unless @page
  @page[:meta][:offset]
end
Also aliased as: offset_value
offset_value()
Alias for: offset
paginate(options = {}) click to toggle source

@return [Pager] Duplicates the pager, updating it with the options supplied. Useful for resource scopes. @see initialize

# File lib/datmachine/pager.rb, line 148
def paginate(options = {})
  dup.instance_eval {
    @page = nil
    @options.update options and self
  }
end
Also aliased as: scoped, where
prev() click to toggle source

@return [Array, nil] Refreshes the pager’s collection of records with the previous page.

# File lib/datmachine/pager.rb, line 124
def prev
  load! unless @page
  prev_uri = @page[:meta][:prev]
  load_from prev_uri, nil unless prev_uri.nil?
end
reload()
Alias for: load!
resource_class() click to toggle source
# File lib/datmachine/pager.rb, line 27
def resource_class
  return @resource_class unless @resource_class.nil?
  load! unless @page
  @resource_class
end
scoped(options = {})
Alias for: paginate
start() click to toggle source

@return [Array, nil] Refreshes the pager’s collection of records with the first page.

# File lib/datmachine/pager.rb, line 132
def start
  load! unless @page
  first_page = @page[:meta][:first]
  load_from first_page, nil unless first_page.nil?
end
total() click to toggle source
# File lib/datmachine/pager.rb, line 47
def total
  load! unless @page
  @page[:meta][:total]
end
where(options = {})
Alias for: paginate

Private Instance Methods

adjust_pagination_params(original) click to toggle source
# File lib/datmachine/pager.rb, line 217
def adjust_pagination_params(original)
  adjusted = original.dup
  per = adjusted.delete(:per)
  adjusted[:limit] = per unless per.nil?
  page = adjusted.delete(:page)
  adjusted[:offset] = (adjusted[:limit] || DEFAULT_LIMIT) * ([page, 1].max - 1) unless page.nil?
  adjusted
end
load_from(uri, params) click to toggle source
# File lib/datmachine/pager.rb, line 185
def load_from(uri, params)
  parsed_uri = URI.parse(uri)

  params ||= {}
  params = adjust_pagination_params(params)

  unless parsed_uri.query.nil?
    # The reason we don't use CGI::parse here is because
    # the Datmachine api currently can't handle variable[]=value.
    # Faraday ends up encoding a simple query string like:
    # {"limit"=>["10"], "offset"=>["0"]}
    # to limit[]=10&offset[]=0 and that's cool, but
    # we have to make sure Datmachine supports it.
    query_params = parse_query(parsed_uri.query)
    params.merge! query_params
    parsed_uri.query = nil
  end

  response = Datmachine.get parsed_uri.to_s, params
  @page = Datmachine::Utils.indifferent_read_access response.body

  #@href = @page[:meta][:href]
  # resource_class?
  hypermedia_key = (@page.keys.map{|k| k.to_sym } - [:meta, :links]).first
  
  unless hypermedia_key.nil?
    @resource_class = ("Datmachine::" + Datmachine::Utils.classify(hypermedia_key)).constantize
  end
  
  @page
end
parse_query(qs, d = nil) click to toggle source

Stolen from Mongrel, with some small modifications: Parses a query string by breaking it up at the ‘&’ and ‘;’ characters. You can also use this to parse cookies by changing the characters used in the second parameter (which defaults to ‘&;’).

# File lib/datmachine/pager.rb, line 231
def parse_query(qs, d = nil)
  params = {}

  (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
    k, v = p.split('=', 2).map { |x| CGI::unescape(x) }
    if (cur = params[k])
      if cur.class == Array
        params[k] << v
      else
        params[k] = [cur, v]
      end
    else
      params[k] = v
    end
  end

  params
end