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