diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index 1059fc032dc3ce0929b3f4f7b730922b9ccaab02..b8a856f001e7d4df0d4400c7ef006016a5edb38f 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -31,7 +31,7 @@ def self.build(model, name, scope, options, &block) builder = new(name, scope, options, &block) reflection = builder.build(model) - builder.define_accessors model + builder.define_accessors model, reflection builder.define_callbacks model, reflection builder.define_extensions model reflection @@ -82,7 +82,7 @@ def define_callbacks(model, reflection) # # Post.first.comments and Post.first.comments= methods are defined by this method... - def define_accessors(model) + def define_accessors(model, reflection) mixin = model.generated_feature_methods define_readers(mixin) define_writers(mixin) diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index 51d963e18dddad4107cb5130763a17cb6d7d5b20..a2f4758b571b2cab8b3c9e8184b16419f5241504 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -8,10 +8,6 @@ def valid_options super + [:foreign_type, :polymorphic, :touch] end - def constructable? - !options[:polymorphic] - end - def valid_dependent_options [:destroy, :delete] end @@ -22,7 +18,7 @@ def define_callbacks(model, reflection) add_touch_callbacks(model, reflection) if options[:touch] end - def define_accessors(mixin) + def define_accessors(mixin, reflection) super add_counter_cache_methods mixin end @@ -58,7 +54,7 @@ def belongs_to_counter_cache_after_update(association, reflection) if (@_after_create_counter_called ||= false) @_after_create_counter_called = false - elsif attribute_changed?(foreign_key) && !new_record? && association.constructable? + elsif attribute_changed?(foreign_key) && !new_record? && reflection.constructable? model = reflection.klass foreign_key_was = attribute_was foreign_key foreign_key = attribute foreign_key diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb index 62d454ce55d25dc6559ddce810fd2cda5b714fbf..accd29e5efac7b9c3511237e3831cb8588130fbc 100644 --- a/activerecord/lib/active_record/associations/builder/has_one.rb +++ b/activerecord/lib/active_record/associations/builder/has_one.rb @@ -10,10 +10,6 @@ def valid_options valid end - def constructable? - !options[:through] - end - def valid_dependent_options [:destroy, :delete, :nullify, :restrict_with_error, :restrict_with_exception] end diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb index d97c0e9afd4f4e9befad31762dc88f34582bfcff..10d568ebc072d1ad2de17abf0d26b344d4465b47 100644 --- a/activerecord/lib/active_record/associations/builder/singular_association.rb +++ b/activerecord/lib/active_record/associations/builder/singular_association.rb @@ -6,13 +6,9 @@ def valid_options super + [:remote, :dependent, :counter_cache, :primary_key, :inverse_of] end - def constructable? - true - end - - def define_accessors(model) + def define_accessors(model, reflection) super - define_constructors(model.generated_feature_methods) if constructable? + define_constructors(model.generated_feature_methods) if reflection.constructable? end # Defines the (build|create)_association methods for belongs_to or has_one association diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index f47282b7fdc48c5c7f6b577c2d07becb302d428f..263ba922da7e6fa3900c7540370572eacf3718c9 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -200,6 +200,7 @@ def initialize(macro, name, scope, options, active_record) @automatic_inverse_of = nil @type = options[:as] && "#{options[:as]}_type" @foreign_type = options[:foreign_type] || "#{name}_type" + @constructable = calculate_constructable(macro, options) end # Returns a new, unsaved instance of the associated class. +attributes+ will @@ -208,6 +209,10 @@ def build_association(attributes, &block) klass.new(attributes, &block) end + def constructable? # :nodoc: + @constructable + end + def table_name klass.table_name end @@ -379,6 +384,17 @@ def actual_source_reflection # FIXME: this is a horrible name end private + def calculate_constructable(macro, options) + case macro + when :belongs_to + !options[:polymorphic] + when :has_one + !options[:through] + else + true + end + end + # Attempts to find the inverse association name automatically. # If it cannot find a suitable inverse association name, it returns # nil.