user2012677
user2012677

Reputation: 5755

ActiveRecord::Base.transaction with Rails .save

It is my understanding that wrapping .save! in ActiveRecord::Base.transaction will make sure all the models (User, Profile, and Setting) to save together or none at all.

However, I was also told that including .save! with all the models.save! methods will also do that. So essentially, both version 1 and 2 are the same. I have a feeling I am wrong, so what is the difference?

Thank you

Version 1

def save
  if valid?
    ActiveRecord::Base.transaction do
      User.save!
      Profile.save!
      Setting.save!
    end
  else
    false
  end
end

Version 2

def save
  if valid?
      User.save!
      Profile.save!
      Setting.save!      
  else
    false
  end
end

Reference: https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

Upvotes: 1

Views: 3881

Answers (1)

Ratnam Yadav
Ratnam Yadav

Reputation: 196

In the first case if any of save! statement fails then all the previous saved models will be rolled back. For ex: If setting.save! fails then setting.save!, user.save! and profile.save! will be rolled back.

But in second case if any save! statement fails then it will only rollback that statement and it will also raise an exception. For ex: If setting.save! fails then only setting.save! will be rolled back.

Both statements will work same only in 1 case when the first statement fails 'user.save!' as exception will be raised and in second case subsequent statement will not be executed

The difference between save and save! is that the latter will raise an exception but both will not save the value of object to table if validations fail.

Upvotes: 5

Related Questions