aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations.rb
diff options
context:
space:
mode:
authorJeff Dean <jeff@zilkey.com>2010-12-03 23:16:45 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2010-12-08 15:21:18 -0800
commit7ecee054a322e214e4f285b1a8327751bd79a418 (patch)
treef605598c50f78cfba2deb5345ed80dfe0d739360 /activerecord/lib/active_record/associations.rb
parente924814b28d655242a49f543cf453d55712071b1 (diff)
downloadrails-7ecee054a322e214e4f285b1a8327751bd79a418.tar.gz
rails-7ecee054a322e214e4f285b1a8327751bd79a418.tar.bz2
rails-7ecee054a322e214e4f285b1a8327751bd79a418.zip
Setting the id of a belongs_to object updates all referenced objects [#2989 state:resolved]
Diffstat (limited to 'activerecord/lib/active_record/associations.rb')
-rw-r--r--activerecord/lib/active_record/associations.rb37
1 files changed, 37 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 0d9171d876..4711522b00 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1223,12 +1223,14 @@ module ActiveRecord
if reflection.options[:polymorphic]
association_accessor_methods(reflection, BelongsToPolymorphicAssociation)
+ association_foreign_type_setter_method(reflection)
else
association_accessor_methods(reflection, BelongsToAssociation)
association_constructor_method(:build, reflection, BelongsToAssociation)
association_constructor_method(:create, reflection, BelongsToAssociation)
end
+ association_foreign_key_setter_method(reflection)
add_counter_cache_callbacks(reflection) if options[:counter_cache]
add_touch_callbacks(reflection, options[:touch]) if options[:touch]
@@ -1555,6 +1557,41 @@ module ActiveRecord
end
end
+ def association_foreign_key_setter_method(reflection)
+ setters = reflect_on_all_associations(:belongs_to).map do |belongs_to_reflection|
+ if belongs_to_reflection.primary_key_name == reflection.primary_key_name
+ "association_instance_set(:#{belongs_to_reflection.name}, nil);"
+ end
+ end.compact.join
+
+ class_eval <<-FILE, __FILE__, __LINE__ + 1
+ def #{reflection.primary_key_name}=(new_id)
+ write_attribute :#{reflection.primary_key_name}, new_id
+ if #{reflection.primary_key_name}_changed?
+ #{ setters }
+ end
+ end
+ FILE
+ end
+
+ def association_foreign_type_setter_method(reflection)
+ setters = reflect_on_all_associations(:belongs_to).map do |belongs_to_reflection|
+ if belongs_to_reflection.options[:foreign_type] == reflection.options[:foreign_type]
+ "association_instance_set(:#{belongs_to_reflection.name}, nil);"
+ end
+ end.compact.join
+
+ field = reflection.options[:foreign_type]
+ class_eval <<-FILE, __FILE__, __LINE__ + 1
+ def #{field}=(new_id)
+ write_attribute :#{field}, new_id
+ if #{field}_changed?
+ #{ setters }
+ end
+ end
+ FILE
+ end
+
def add_counter_cache_callbacks(reflection)
cache_column = reflection.counter_cache_column