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