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.