I've encountered what seems like an odd omission in the behaviour of belongs_to associations: if you assign to the foreign key attribute, it doesn't update the associated object (or mark a previously loaded one as stale) until you explicitly save or reload it.
Let's say we have a Company model, which belongs_to :city :
torchbox = Company.find_by_name('Torchbox')
=> #<Company id: 1, name: "Torchbox", city_id: 1>
torchbox.city
=> #<City id: 1, name: "Oxford">
torchbox.city_id = 2
=> 2
torchbox.city
=> #<City id: 1, name: "Oxford">
(Would have expected City id: 2 to be returned here...)
I've come up with a 6-line patch (see below) and accompanying plugin to fix this, but I get the feeling that for something so elementary to have gone unfixed for so long, there must be some perceived good reason why it works the way it does. If so, what's the reason? And if not, is this a patch that's worth pushing through the official channels?
- Matt
diff --git a/activerecord/lib/active_record/associations.rb b/ activerecord/lib/active_record/associations.rb index 0809b27..7135e50 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1094,6 +1094,13 @@ module ActiveRecord instance_variable_set(ivar, new_value.nil? ? nil : association) end
+ if association_proxy_class == BelongsToAssociation + define_method("#{reflection.primary_key_name}=") do | target_id| + instance_variable_set(ivar, nil) + self["#{reflection.primary_key_name}"] = target_id + end + end