lib/ninja_model/associations.rb in ninja-model-0.8.1 vs lib/ninja_model/associations.rb in ninja-model-0.9.0
- old
+ new
@@ -1,125 +1,87 @@
module NinjaModel
+ module Associations
+ extend ActiveSupport::Concern
- class Base
- class << self
- def has_one(association_id, options = {})
- reflection = create_has_one_reflection(association_id, options)
- association_accessor_methods(reflection, Associations::HasOneAssociation)
- # TODO: Implement the build/create association methods
- #association_constructor_method(:build, reflection, HasOneAssociation)
- #association_constructor_method(:create, reflection, HasOneAssociation)
- #configure_dependency_for_has_one(reflection)
- end
+ autoload :Association, 'ninja_model/associations/association'
+ autoload :AssociationProxy, 'ninja_model/associations/association_proxy'
+ autoload :AssociationScope, 'ninja_model/associations/association_scope'
+ autoload :BelongsToAssociation, 'ninja_model/associations/belongs_to_association'
+ autoload :CollectionAssociation, 'ninja_model/associations/collection_association'
+ autoload :CollectionProxy, 'ninja_model/associations/collection_proxy'
+ autoload :HasOneAssociation, 'ninja_model/associations/has_one_association'
+ autoload :HasManyAssociation, 'ninja_model/associations/has_many_association'
+ autoload :SingularAssociation, 'ninja_model/associations/singular_association'
- def belongs_to(association_id, options = {})
- reflection = create_belongs_to_reflection(association_id, options)
- association_accessor_methods(reflection, Associations::BelongsToAssociation)
- # TODO: Implement the build/create association methods
- #association_constructor_method(:build, reflection, BelongsToAssociation)
- #association_constructor_method(:create, reflection, BelongsToAssociation)
- end
+ module Builder
+ autoload :Association, 'ninja_model/associations/builder/association'
+ autoload :SingularAssociation, 'ninja_model/associations/builder/singular_association'
+ autoload :CollectionAssociation, 'ninja_model/associations/builder/collection_association'
+ autoload :HasMany, 'ninja_model/associations/builder/has_many'
+ autoload :BelongsTo, 'ninja_model/associations/builder/belongs_to'
+ autoload :HasOne, 'ninja_model/associations/builder/has_one'
+ end
- def has_many(association_id, options = {})
- reflection = create_has_many_reflection(association_id, options)
- collection_accessor_methods(reflection, Associations::HasManyAssociation)
- end
+ attr_reader :association_cache
- private
+ def association(name)
+ association = association_instance_get(name)
- def create_has_one_reflection(association, options = {})
- create_reflection(:has_one, association, options, self)
+ if association.nil?
+ reflection = self.class.reflect_on_association(name)
+ association = reflection.association_class.new(self, reflection)
+ association_instance_set(name, association)
end
+ association
+ end
- def create_has_many_reflection(association, options = {})
- create_reflection(:has_many, association, options, self)
- end
+ private
- def create_belongs_to_reflection(association, options = {})
- create_reflection(:belongs_to, association, options, self)
- end
+ def association_instance_get(name)
+ @association_cache[name.to_sym]
+ end
- def association_accessor_methods(reflection, association_proxy_class)
- redefine_method(reflection.name) do |*params|
- association = association_instance_get(reflection.name)
+ def association_instance_set(name, association)
+ @association_cache[name.to_sym] = association
+ end
- if association.nil?
- association = association_proxy_class.new(self, reflection)
- retval = association.reload
- if retval.nil? and association_proxy_class == Associations::BelongsToAssociation
- association_instance_set(reflection.name, nil)
- return nil
- end
- association_instance_set(reflection.name, association)
- end
- association.target.nil? ? nil : association
+ module ClassMethods
+ def add_autosave_association_callbacks(reflection)
+ end
+ def has_one(name, options = {})
+ klass = compute_klass(name, :has_one, options)
+ if NinjaModel.ninja_model?(klass)
+ Builder::HasOne.build(self, name, options)
+ else
+ ActiveRecord::Associations::Builder::HasOne.build(self, name, options)
end
-
- redefine_method("loaded_#{reflection.name}?") do
- association = association_instance_get(reflection.name)
- association && association.loaded?
- end
-
- redefine_method("#{reflection.name}=") do |new_value|
- association = association_instance_get(reflection.name)
- if association.nil? || association.target != new_value
- association = association_proxy_class.new(self, reflection)
- end
-
- association.replace(new_value)
- association_instance_set(reflection.name, new_value.nil? ? nil : association)
- end
-
- redefine_method("set_#{reflection.name}_target") do |target|
- return if target.nil? and association_proxy_class == Associations::BelongsToAssociation
- association = association_proxy_class.new(self, reflection)
- association.target = target
- association_instance_set(reflection.name, association)
- end
end
- def collection_accessor_methods(reflection, association_proxy_class, writer = true)
- collection_reader_method(reflection, association_proxy_class)
-
- if writer
- redefine_method("#{reflection.name}=") do |new_value|
- association = send(reflection.name)
- association.replace(new_value)
- association
- end
+ def belongs_to(name, options = {}, &extension)
+ klass = compute_klass(name, :belongs_to, options)
+ if NinjaModel.ninja_model?(klass)
+ Builder::BelongsTo.build(self, name, options)
+ else
+ ActiveRecord::Associations::Builder::BelongsTo.build(self, name, options)
end
end
- def collection_reader_method(reflection, association_proxy_class)
- redefine_method(reflection.name) do |*params|
- association = association_instance_get(reflection.name)
-
- if association.nil?
- association = association_proxy_class.new(self, reflection)
- end
- association_instance_set(reflection.name, association)
- association
+ def has_many(name, options = {}, &extension)
+ klass = compute_klass(name, :has_many, options)
+ if NinjaModel.ninja_model?(klass)
+ Builder::HasMany.build(self, name, options)
+ else
+ ActiveRecord::Associations::Builder::HasMany.build(self, name, options)
end
end
- end
- end
- module Associations
+ private
- autoload :AssociationProxy, 'ninja_model/associations/association_proxy'
- autoload :HasOneAssociation, 'ninja_model/associations/has_one_association'
- autoload :HasManyAssociation, 'ninja_model/associations/has_many_association'
- autoload :BelongsToAssociation, 'ninja_model/associations/belongs_to_association'
-
- def association_instance_get(name)
- ivar = "@#{name}"
- if instance_variable_defined?(ivar)
- association = instance_variable_get(ivar)
- association if association.respond_to?(:loaded?)
+ def compute_klass(name, macro, options)
+ klass = options[:class_name] || name
+ klass = klass.to_s.camelize
+ klass = klass.singularize if macro.eql?(:has_many)
+ klass = compute_type(klass)
end
- end
-
- def association_instance_set(name, association)
- instance_variable_set("@#{name}", association)
end
end
end