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