lib/api_resource/scopes.rb in api_resource-0.4.3 vs lib/api_resource/scopes.rb in api_resource-0.5.0

- old
+ new

@@ -1,35 +1,72 @@ module ApiResource module Scopes + extend ActiveSupport::Concern - module ClassMethods def scopes return self.related_objects[:scopes] end - # Called by base.rb - # @param name is the name of the scope from the json - # @param hsh is always a hash with the arguments for the scope - def scope(name, hsh) - raise ArgumentError, "Expecting an attributes hash given #{hsh.inspect}" unless hsh.is_a?(Hash) - self.related_objects[:scopes][name.to_sym] = hsh - # we also need to define a class method for each scope - self.instance_eval <<-EOE, __FILE__, __LINE__ + 1 - def #{name}(*args) - return #{ApiResource::Associations::ResourceScope.class_factory(hsh)}.new(self, :#{name}, *args) - end - EOE - end - def scope?(name) - self.related_objects[:scopes][name.to_sym].present? + self.related_objects[:scopes].has_key?(name.to_sym) end def scope_attributes(name) raise "No such scope #{name}" unless self.scope?(name) self.related_objects[:scopes][name.to_sym] + end + + # Called by base.rb + # @param scope_name is the scope_name of the scope from the json + # e.g. paged + # + # @param scope_definition is always a hash with the arguments for the scope + # e.g. {:page => "req", "per_page" => "opt"} + def scope(scope_name, scope_definition) + + unless scope_definition.is_a?(Hash) + raise ArgumentError, "Expecting an attributes hash given #{scope_definition.inspect}" + end + + self.related_objects[:scopes][scope_name.to_sym] = scope_definition + + self.class_eval do + + define_singleton_method(scope_name) do |*args| + + arg_names = scope_definition.keys + arg_types = scope_definition.values + + finder_opts = { + scope_name => {} + } + + arg_names.each_with_index do |arg_name, i| + + # If we are dealing with a scope with multiple args + if arg_types[i] == :rest + finder_opts[scope_name][arg_name] = + args.slice(i, args.count) + # Else we are only dealing with a single argument + else + if arg_types[i] == :req || args[i].present? + finder_opts[scope_name][arg_name] = args[i] + end + end + end + + # if we have nothing at this point we should just pass 'true' + if finder_opts[scope_name] == {} + finder_opts[scope_name] = true + end + + ApiResource::Associations::ResourceScope.new( + self, finder_opts + ) + end + end end end def scopes return self.class.scopes