lib/zendesk_api/collection.rb in zendesk_api-0.3.14 vs lib/zendesk_api/collection.rb in zendesk_api-0.4.0.rc1

- old
+ new

@@ -8,12 +8,10 @@ include ZendeskAPI::Sideloading # Options passed in that are automatically converted from an array to a comma-separated list. SPECIALLY_JOINED_PARAMS = [:ids, :only] - include Rescue - # @return [ZendeskAPI::Association] The class association attr_reader :association # @return [Faraday::Response] The last response attr_reader :response @@ -43,41 +41,39 @@ else @fetchable = true end end - # Passes arguments and the proper path to the resource class method. - # @param [Hash] attributes Attributes to pass to Create#create - def create(attributes = {}) - attributes.merge!(:association => @association) - @resource_class.create(@client, @options.merge(attributes)) - end + methods = %w{create find update destroy} + methods += methods.map {|method| method + "!"} + methods.each do |deferrable| + # Passes arguments and the proper path to the resource class method. + # @param [Hash] options Options or attributes to pass + define_method deferrable do |*args| + unless @resource_class.respond_to?(deferrable) + raise NoMethodError.new("undefined method \"#{deferrable}\" for #{@resource_class}", deferrable, args) + end - # (see #create) - def find(opts = {}) - opts.merge!(:association => @association) - @resource_class.find(@client, @options.merge(opts)) - end + opts = args.last.is_a?(Hash) ? args.pop : {} + opts.merge!(:association => @association) - # (see #create) - def update(opts = {}) - opts.merge!(:association => @association) - @resource_class.update(@client, @options.merge(opts)) + @resource_class.send(deferrable, @client, @options.merge(opts)) + end end - # (see #create) - def destroy(opts = {}) - opts.merge!(:association => association) - @resource_class.destroy(@client, @options.merge(opts)) - end - # @return [Number] The total number of resources server-side (disregarding pagination). def count fetch @count || -1 end + # @return [Number] The total number of resources server-side (disregarding pagination). + def count! + fetch! + @count || -1 + end + # Changes the per_page option. Returns self, so it can be chained. No execution. # @return [Collection] self def per_page(count) clear_cache if count @options["per_page"] = count @@ -101,21 +97,17 @@ end # Saves all newly created resources stored in this collection. # @return [Collection] self def save - if @resources - @resources.map! do |item| - unless !item.respond_to?(:save) || item.changes.empty? - item.save - end + _save + end - item - end - end - - self + # Saves all newly created resources stored in this collection. + # @return [Collection] self + def save! + _save(:save!) end # Adds an item (or items) to the list of side-loaded resources to request # @option sideloads [Symbol or String] The item(s) to sideload def include(*sideloads) @@ -144,11 +136,11 @@ @association.generate_path(:with_parent => true) end # Executes actual GET from API and loads resources into proper class. # @param [Boolean] reload Whether to disregard cache - def fetch(reload = false) + def fetch!(reload = false) if @resources && (!@fetchable || !reload) return @resources elsif association && association.options.parent && association.options.parent.new_record? return @resources = [] end @@ -158,36 +150,46 @@ @query = nil @resources end - rescue_client_error :fetch, :with => lambda { Array.new } + def fetch(*args) + fetch!(*args) + rescue Faraday::Error::ClientError => e + [] + end # Alias for fetch(false) def to_a fetch end + # Alias for fetch!(false) + def to_a! + fetch! + end + # Calls #each on every page with the passed in block # @param [Block] block Passed to #each - def each_page(start_page = @options["page"], &block) - page(start_page) - clear_cache + def all!(start_page = @options["page"], &block) + _all(start_page, :bang, &block) + end - while !empty? - each do |resource| - arguments = [resource, @options["page"] || 1] + # Calls #each on every page with the passed in block + # @param [Block] block Passed to #each + def all(start_page = @options["page"], &block) + _all(start_page, &block) + end - if block.arity >= 0 - arguments = arguments.take(block.arity) - end + def each_page!(*args, &block) + warn "ZendeskAPI::Collection#each_page! is deprecated, please use ZendeskAPI::Collection#all!" + all!(*args, &block) + end - block.call(*arguments) - end - - self.next - end + def each_page(*args, &block) + warn "ZendeskAPI::Collection#each_page is deprecated, please use ZendeskAPI::Collection#all" + all(*args, &block) end # Replaces the current (loaded or not) resources with the passed in collection # @option collection [Array] The collection to replace this one with # @raise [ArgumentError] if any resources passed in don't belong in this collection @@ -232,11 +234,10 @@ def clear_cache @resources = nil @count = nil @next_page = nil @prev_page = nil - @query = nil end # @private def to_ary; nil; end @@ -274,9 +275,42 @@ if @next_page =~ /page=(\d+)/ @options["page"] = $1.to_i - 1 elsif @prev_page =~ /page=(\d+)/ @options["page"] = $1.to_i + 1 end + end + + def _all(start_page = @options["page"], bang = false, &block) + page(start_page) + clear_cache + + while (bang ? fetch! : fetch) && !empty? + each do |resource| + arguments = [resource, @options["page"] || 1] + + if block.arity >= 0 + arguments = arguments.take(block.arity) + end + + block.call(*arguments) + end + + self.next + end + end + + def _save(method = :save) + if @resources + @resources.map! do |item| + if item.respond_to?(method) && !item.changes.empty? + item.send(method) + end + + item + end + end + + self end ## Initialize def join_special_params