accepts_nested_attributes_for is Creating New Records; Gotcha!
accepts_nested_attributes_for is a really powerful method in Rails because it allows a model to alter related models through itself. However, it has a pretty big gotcha.
An example using accepts_nested_attributes_for is where a user model which belongs_to an alias model, i.e.
#user.rb
class User < ActiveRecord::Base
end#alias.rb
class Alias < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user
end
This allows the Alias model to change the user by passing a hash key user_attributes i.e.
Alias.first.user.name
>> "Alice"
Alias.first.update_attributes(
{
:user_attributes => {
:id => 1,
:name => "Bob"
}
})Alias.first.user.name
>> "Bob"
The gotcha exists if you do not pass the :id symbol in the attributes hash, i.e.
Alias.first.user_id
>> 1
Alias.first.update_attributes(
{
:user_attributes => {
:name => "Bob"
}
})Alias.first.user_id
>> 2
This behaviour is documented, it is just not what I would have expected.
To "fix" this (if you do not want to pass the id every time) you can set the :update_only flag to true, i.e.
#alias.rb
class Alias < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user,
:update_only => true
end