0

I have the following:

class User < ActiveRecord::Base
  has_one :blog
end

class Blog < ActiveRecord::Base
  belongs_to :user
end

If I do this:

@user = User.new
@blog = Blog.new

@blog.title = 'hi'
@user.blog = @blog

@user.save

Why/how is it saving the @blog object to the database without me saving the @blog object? For example, If I continue from the above example:

@user.reload
@user.blog.title
#=> 'hi'

It magically has saved @blog to the db!

Strangely, if my @blog has other associations, it doesn't seem to save them to the database.

What's the general behavior/logic behind that? My @blog has other associations and I'd like to be able to simply call @user.save and have it save all associations. How can I do that?

tshepang
  • 12,111
  • 21
  • 91
  • 136
user3621156
  • 65
  • 1
  • 7

1 Answers1

1

The behavior is that associations are "autosaved" when the autosave option is not specified, i.e. the autosave option is by default is true with the condition of "new association records are saved but the updated associations are not saved".

The following description taken from the Rails API docs on "Active Record Autosave Association" explains this feature clearly:

AutosaveAssociation is a module that takes care of automatically saving associated records when their parent is saved. In addition to saving, it also destroys any associated records that were marked for destruction. (See mark_for_destruction and marked_for_destruction?).

Saving of the parent, its associations, and the destruction of marked associations, all happen inside a transaction. This should never leave the database in an inconsistent state.

If validations for any of the associations fail, their error messages will be applied to the parent.

Note that it also means that associations marked for destruction won't be destroyed directly. They will however still be marked for destruction.

Note that autosave: false is not same as not declaring :autosave. When the :autosave option is not present then new association records are saved but the updated association records are not saved.

If you do not want the associated objects saved or destroyed when parent objects are created/updated or destroyed then specify autosave: false when declaring associations:

class User < ActiveRecord::Base
  has_one :blog, autosave: false
end

This way, when an user is created, you won't see it's associated blog saved. You'll have to save it manually calling save on the associated blog instance.

vee
  • 38,255
  • 7
  • 74
  • 78