lib/balanced/pager.rb in balanced-0.8.2 vs lib/balanced/pager.rb in balanced-1.0.beta1
- old
+ new
@@ -5,55 +5,71 @@
DEFAULT_SEP = /[&;] */n
DEFAULT_LIMIT = 10
include Enumerable
+ attr_accessor :href
+ attr_accessor :options
+
# 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
- def initialize uri, options = {}
- @uri = uri
+ def initialize(href, options = {})
+ @href = href
@options = options
@page = nil
@resource_class = nil
end
def resource_class
return @resource_class unless @resource_class.nil?
load! unless @page
- @resource_class = Balanced.from_uri items.first[:uri]
+ @resource_class
end
def first
load! unless @page
- items.first.nil? ? nil : resource_class.construct_from_response(items.first)
+ 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
def total
load! unless @page
- @page[:total]
+ @page[:meta][:total]
end
def limit
load! unless @page
- @page[:limit]
+ @page[:meta][:limit]
end
alias limit_value limit
def offset
load! unless @page
- @page[:offset]
+ @page[:meta][:offset]
end
alias offset_value offset
def items
load! unless @page
- @page[:items]
+ if @resource_class.nil?
+ []
+ else
+ @page[@resource_class.collection_name]
+ end
end
def current_page
(offset / limit) + 1
end
@@ -69,88 +85,105 @@
def each
return enum_for :each unless block_given?
load! unless @page
loop do
- @page[:items].each do |r|
- yield resource_class.construct_from_response r
+ 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[:next_uri].nil?
+ raise StopIteration if @page[:meta][:next].nil?
self.next
end
end
# @return [nil]
- # @see Resource.find_each
+ # @see Resource.fetch_each
# @yield [record]
- def find_each
- return enum_for :find_each unless block_given?
+ def fetch_each
+ return enum_for :fetch_each unless block_given?
begin
each { |record| yield record }
end while self.next
end
# @return [Array, nil] Refreshes the pager's collection of records with
# the next page.
def next
load! unless @page
- next_uri = @page[:next_uri]
+ next_uri = @page[:meta][:next]
load_from next_uri, nil unless next_uri.nil?
end
# @return [Array, nil] Refreshes the pager's collection of records with
# the previous page.
def prev
load! unless @page
- prev_uri = @page[:prev_uri]
+ prev_uri = @page[:meta][:prev]
load_from prev_uri, nil unless prev_uri.nil?
end
# @return [Array, nil] Refreshes the pager's collection of records with
# the first page.
def start
load! unless @page
- first_page = @page[:first_page]
+ first_page = @page[:meta][:first]
load_from first_page, nil unless first_page.nil?
end
# @return [Array, nil] Load (or reload) the pager's collection from the
# original, supplied options.
def load!
- load_from @uri, @options
+ load_from @href, @options
end
alias reload load!
# @return [Pager] Duplicates the pager, updating it with the options
# supplied. Useful for resource scopes.
# @see #initialize
- def paginate options = {}
+ def paginate(options = {})
dup.instance_eval {
@page = nil
@options.update options and self
}
end
alias scoped paginate
alias where paginate
- def all options = {}
+ def all(options = {})
paginate(options).to_a
end
- def find uri
+ def fetch(uri)
if resource_class.respond_to? :find
raise NoMethodError,
"#find must be called on #{resource_class} directly"
end
- resource_class.find uri
+ resource_class.fetch uri
end
+ def create(options={})
+ opts = Balanced::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 = Balanced.from_href(@href)
+ end
+ @resource_class.new(opts).save
+ end
+
private
- def load_from uri, params
+ def load_from(uri, params)
parsed_uri = URI.parse(uri)
params ||= {}
params = adjust_pagination_params(params)
@@ -165,11 +198,19 @@
params.merge! query_params
parsed_uri.query = nil
end
response = Balanced.get parsed_uri.to_s, params
- @page = Balanced::Utils.hash_with_indifferent_read_access response.body
- @uri = @page[:uri]
+ @page = Balanced::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 = Balanced.from_hypermedia_registry(hypermedia_key.to_s)
+ end
+
+ @page
end
def adjust_pagination_params(original)
adjusted = original.dup
per = adjusted.delete(:per)
\ No newline at end of file