Is it the case that the entire restful verb is under a single all encompassing transaction? That is to say, if I raise a Error in the validation or callbacks at any point in the handling of a UPDATE, DELETE, or CREATE operation, is every database operation that I may have performed in previous callbacks also rolled back? Succinctly, does raising a Error on any callback or validation make it such that no change at all occurs in the database for that verb action?
Some methods (create, destroy) go to the database immediately. Transactions occur by using the transaction method on classes derived from ActiveRecord as follows:
Student.transaction do
Course.transaction do
course.enroll(student)
student.units += course.units
end
end
(This example is for multiple databases. For a single database, you only need one transaction.)
You can then rollback on these transactions, and exceptions thrown within the transaction are propagated after the rollback.
This depends upon the database having transactions.
NB: save and destroy are wrapped in transactions.
By default there is no database code written inside a transaction, you need to tell it to do that in the code.
def create
Model.transaction do
Model.create!(params[:model])
Model.association.create!(params[:association])
end
rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
flash[:notice] = "That record could not be saved."
render :action => "new"
end
Using the #create! methods will attempt to save the record and if they fail they will raise an exception which will then rollback any code already performed inside the transaction block.
If you don't rescue the action you will be redirected to (I think) a 405.html in your public directory if one exists.
Is it the case that the entire restful verb is under a single all encompassing transaction?
No
if I raise a Error in the validation or callbacks at any point in the handling of a UPDATE, DELETE, or CREATE operation, is every database operation that I may have performed in previous callbacks also rolled back?
No.
does raising a Error on any callback or validation make it such that no change at all occurs in the database for that verb action?
No.
If you desire this behaviour you can either explicitly create transactions in your controller (see the examples provided by other users), or use an around_filter
to attach the behaviour to all your restful actions.