lib/api_resource/scopes.rb in api_resource-0.6.21 vs lib/api_resource/scopes.rb in api_resource-0.6.22

- old
+ new

@@ -4,10 +4,11 @@ extend ActiveSupport::Concern module ClassMethods # TODO: calling these methods should force loading of the resource definition def scopes + self.reload_resource_definition return self.related_objects[:scopes] end def scope?(name) self.related_objects[:scopes].has_key?(name.to_sym) @@ -66,11 +67,11 @@ end end end - # + # # Apply scopes from params based on our resource # definition # def add_scopes(params, base = self) # scopes are stored as strings but we want to allow @@ -88,25 +89,58 @@ end end return base end + # + # Add our dynamic scopes based on a set of params + # + # @param params [Hash] User-supplied params + # @param base [ApiResource::Conditions::AbstractCondition, Class] Base + # Scope + # + # @return [ApiResource::Conditions::AbstractCondition] [description] def add_dynamic_scopes(params, base) self.dynamic_scopes.each_pair do |name, args| - next if params[name].blank? + # make sure we have all required arguments + next unless self.check_required_scope_args(args, params[name]) + + # the args we will apply caller_args = [] - args.each_pair do |subkey, type| - if type == :req || params[name][subkey].present? - caller_args << params[name][subkey] + + # iterate through our args and add them to an array to send to our + # scope + args.keys.each do |subkey| + # we only apply things that are present or explicitly false + if val = self.get_scope_arg_value(subkey, params[name][subkey]) + caller_args << val end end + # call our scope with the supplied args base = base.send(name, *caller_args) end return base end # + # Check if we have supplied all of the necessary + # @param scope [Hash] [Scope Definition + # @param params [Hash] [Supplied params] + # + # @return [Boolean] Validity + def check_required_scope_args(scope, params) + # make sure we have a hash and it has values + return false unless params.is_a?(Hash) && params.present? + # find required values + required = scope.select{ |k,v| v.to_sym == :req }.keys + # make sure we have all of the required values, we allow false + required.all? { |key| + params[key].present? || params[key] == false + } + end + + # # Wrapper method to define all scopes from the resource definition # # @return [Boolean] true def define_all_scopes if self.resource_definition["scopes"] @@ -115,11 +149,34 @@ end end true end + # + # Scopes that require arguments + # + # @return [Hash] def dynamic_scopes self.scopes.select { |name, args| args.present? } + end + + # + # Get the parsed/formatted arguments to send to the server + # + # @param key [String, Symbol] Key name for the scope value + # @param value [String, Integer, Symbol] Value for the scope + # + # @return [String, Integer, Symbol, Date] Parsed/formatted value + def get_scope_arg_value(key, value) + # cast to string to avoid incorred blank? behavior for us + return "false" if value == false + # if we havea date field, try to parse, falling back to the original + # value + if key.to_s =~ /date/ + value = Date.parse(value) rescue value + end + # return the final value + value end def static_scopes self.scopes.select { |name, args| args.blank? }.keys end