lib/restly/associations/base.rb in restly-0.0.1.alpha.1 vs lib/restly/associations/base.rb in restly-0.0.1.alpha.2
- old
+ new
@@ -10,26 +10,97 @@
@owner = owner
@association_class = [@namespace, options.delete(:class_name)].compact.join('::').constantize
@options = options
end
- def collection?
- false
+ def load(parent, options)
+
+ # Merge Options
+ options.reverse_merge!(self.options)
+
+ # Authorize and Set Path
+ association = authorize(options[:authorize]).with_path(parent, options[:path])
+
+ # Load Collection or Instance
+ collection? ? association.load_collection(parent) : association.load_instance(parent)
end
- def build(*args)
- new_instance = @association_class.new(*args)
- new_instance.write_attribute("#{@owner.resource_name}_id") if @association_class.respond_to?("#{@owner.resource_name}_id") && !self.class.send(:reflect_on_resource_association, :custom_pages).embedded?
- new_instance
+ def load_collection(parent, association_class = self.association_class)
+ raise Restly::Error::AssociationError, "Not a collection" unless collection?
+ Restly::Proxies::Associations::Collection.new(association_class.all, parent)
end
+ def load_instance(parent, association_class = self.association_class)
+ raise Restly::Error::AssociationError, "Not an instance" if collection?
+ instance = if (foreign_key = parent.attributes["#{name}_id"])
+ association_class.find(foreign_key)
+ else
+ association_class.instance_from_response association_class.connection.get(association_class.path)
+ end
+ Restly::Proxies::Associations::Instance.new(instance, parent)
+ end
+
+ def valid?(val)
+ valid_instances = Array.wrap(val).reject{ |item| item.resource_name == @association_class.resource_name }.empty?
+ raise Restly::Error::InvalidObject, "#{val} is not a #{association_class}" unless valid_instances
+ end
+
+ # Stubs
+ def stub(parent, attributes)
+ return nil if !parent.is_a?(Restly::Base) || !attributes.present?
+ collection? ? stub_collection(parent, attributes) : stub_instance(parent, attributes)
+ end
+
+ def stub_collection(parent, attributes)
+ collection = attributes.map{ |item_attrs| association_class.new(item_attrs, loaded: embedded?) }
+ Restly::Proxies::Associations::Collection.new(collection, parent)
+ end
+
+ def stub_instance(parent, attributes)
+ instance = association_class.new(attributes, loaded: embedded?)
+ Restly::Proxies::Associations::Instance.new(instance, parent)
+ end
+
+ # Build
+ def build(parent, attributes = nil, options = {})
+ raise NoMethodError, "Build not available for collection." if collection?
+ instance = association_class.new(attributes, options)
+ instance.write_attribute("#{@owner.resource_name}_id", parent.id) if association_class.method_defined?("#{@owner.resource_name}_id")
+ Restly::Proxies::Associations::Instance.new(instance, parent)
+ end
+
+ # Modifiers
+ def authorize(authorization = nil, association_class=self.association_class)
+ duplicate = self.dup
+ duplicate.instance_variable_set :@association_class, if (!association_class.authorized? && @owner.respond_to?(:authorized?) && @owner.authorized?) || authorization
+ association_class.authorize(authorization || @owner.connection)
+ else
+ association_class
+ end
+ duplicate
+ end
+
+ def with_path(parent, path = nil, association_class=self.association_class)
+ duplicate = self.dup
+ duplicate.instance_variable_set :@association_class, if path
+ association_class.with_path(path)
+ else
+ association_class.with_path(association_resource_name, prepend: parent.path)
+ end
+ duplicate
+ end
+
private
- def authorize(klass, authorization = nil)
- if (!klass.authorized? && @owner.respond_to?(:authorized?) && @owner.authorized?) || authorization
- klass.authorize(authorization || @owner.connection)
- else
- klass
- end
+ def collection?
+ false
+ end
+
+ def embedded?
+ false
+ end
+
+ def association_resource_name
+ collection? ? association_class.resource_name.pluralize : association_class.resource_name
end
end
\ No newline at end of file