views:

1925

answers:

3

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?

+1  A: 

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.

Michael Deardeuff
You don't need to nest the transactions like that. Any calls to .transaction just get passed to ActiveRecord::Base. You're literally just calling ActiveRecord::Base.transaction twice
Orion Edwards
This is an example from the rails documentation.
Michael Deardeuff
Ah! I see it is required for multiple databases. Updated.
Michael Deardeuff
+3  A: 

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.

Ryan Bigg
+3  A: 

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.

Orion Edwards