When do I use save!, create! and update_attributes! in Rails? When do I use save!, create! and update_attributes! in Rails? ruby-on-rails ruby-on-rails

When do I use save!, create! and update_attributes! in Rails?


The main difference is how failed saves are handled. When updating an ActiveRecord class the ! version will raise an exception if the record is invalid.

I recommend reading the docs here - http://api.rubyonrails.org/classes/ActiveRecord/Base.html

Using transactions might also be something worth looking into - http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html


Generally you want to use the non-bang versions in your controllers. This allows logic like this:

def update  @model = Model.find params[:id]  if @model.update_attributes params[:model] #returns true of false     # handle success  else     # handle failure  endend

I find myself using the bang versions a lot in tests when I want to make sure I know if something doesn't validate, and isn't saved. I've definitely wasted time debugging tests that were failing because of changed model validations, which would be obvious if I used the bang versions.

e.g.

it "should do something" do   m = Model.create! :foo => 'bar' # will raise an error on validation failure                m.should do_somethingend

In terms of not having invalid data in the database, you should be handling this with ActiveRecord validations (e.g. validates_presence_of :user_id), or defining your own validate method in the model. (http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html) This should prevent saves from occurring if your data isn't valid. If you're really paranoid you can add some constraints to your database. Check the ActiveRecord::Migration docs for how to set up unique indexes and other database constraints in your migrations.

Also in my experience you want to avoid using any custom save or create method whenever possible. If you re-implement functionality included in ActiveRecord you end up paying a price down the road. http://matthewpaulmoore.com/post/5190436725/ruby-on-rails-code-quality-checklist has more to say on this.


What ! (bang) means for update_attributes and save is:

"Raise an exception upon failure" rather than "Return false upon failure"

https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update-21https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save

What ! (bang) means for create is:

"Raise an exception upon failure" rather than "Return the resulting object upon failure"https://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create-21