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
end
end
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_something
end
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.