module ApiResource module Finders extend ActiveSupport::Concern extend ActiveSupport::Autoload autoload :AbstractFinder autoload :ResourceFinder autoload :SingleObjectAssociationFinder autoload :MultiObjectAssociationFinder module ClassMethods # This decides which finder method to call. # It accepts arguments of the form "scope", "options={}" # where options can be standard rails options or :expires_in. # If :expires_in is set, it caches it for expires_in seconds. def find(*arguments) # make sure we have class data before loading self.load_resource_definition scope = arguments.slice!(0) options = arguments.slice!(0) || {} expiry = options.delete(:expires_in) || ApiResource::Base.ttl || 0 ApiResource.with_ttl(expiry.to_f) do case scope when :all then find_every(options) when :first then find_every(options).first when :last then find_every(options).last when :one then find_one(options) else find_single(scope, options) end end end # A convenience wrapper for find(:first, *args). You can pass # in all the same arguments to this method as you can to # find(:first). def first(*args) find(:first, *args) end # A convenience wrapper for find(:last, *args). You can pass # in all the same arguments to this method as you can to # find(:last). def last(*args) find(:last, *args) end # This is an alias for find(:all). You can pass in all the same # arguments to this method as you can to find(:all) def all(*args) find(:all, *args) end def instantiate_collection(collection) collection.collect{|record| instantiate_record(record) } end def instantiate_record(record) self.load_resource_definition ret = self.allocate ret.instance_variable_set( :@attributes, record.with_indifferent_access ) ret.instance_variable_set( :@attributes_cache, HashWithIndifferentAccess.new ) ret end private # Find every resource def find_every(options) begin case from = options[:from] when Symbol instantiate_collection(get(from, options[:params])) when String path = "#{from}#{query_string(options[:params])}" instantiate_collection(connection.get(path, headers) || []) else prefix_options, query_options = split_options(options[:params]) path = collection_path(prefix_options, query_options) instantiate_collection( (connection.get(path, headers) || [])) end rescue ApiResource::ResourceNotFound # Swallowing ResourceNotFound exceptions and return nil - as per # ActiveRecord. nil end end # Find a single resource from a one-off URL def find_one(options) case from = options[:from] when Symbol instantiate_record(get(from, options[:params])) when String path = "#{from}#{query_string(options[:params])}" instantiate_record(connection.get(path, headers)) end end # Find a single resource from the default URL def find_single(scope, options) prefix_options, query_options = split_options(options[:params]) path = element_path(scope, prefix_options, query_options) instantiate_record(connection.get(path, headers)) end end end end