I cant seem to find much information apart from the basics on transactions in rails. I have 5 nested transactions, and am performing the following basic operations: @whatever1.transaction do @whatever2.transaction do .... @whatever2.something = "foo" @whatever1.something = "bar" @whatever1.save @whatever2.save ..... end end ((( I had tried using if''s inside the transaction on the save''s, and it worked for a bit but I then discovered it wasnt fool proof. I assumed that was not the correct way, so I abandoned that route. ))) Now here is where im stuck. How do I know if the transaction committed or rolled back? If it rolled back id obviously want to throw them back, whereas if it committed id want to show a completion page. Something along the following lines: unless @???.committed? render_action ''somewhere'' end Is this how its done (idealogically) or am I on the wrong track? If anyone can give me an example of doing what Im attempting id really appreciate it! Thanks.
Hi Joe,
A transaction is rolled back when an exception is thrown beyond
the .transaction block. You''ll often see:
@a = A.new ...
@b = B.new ...
@b.a = @a
begin
transaction do
raise SomeError unless a.save && b.save
notice "Save successful" # records have been saved, show success
page
redirect_to :show ...
end
rescue SomeError # rollback done
notice "Save failed" # show error message
# assuming postback, render the form again so user can fix input.
end
--
Nicholas Seckar aka. Ulysses
Ok, this was helpful and Ive rewritten my code in the format below. My
raise and rescue are not working though. I did:
raise zipError unless @zip_code = ZipCode.find_by_zip(@user_detail.zip5)
rescue zipError
@user_detail.errors.add("zip5", "does not exist in our
database")
and receive: undefined local variable or method `zipError''
Im assuming I cant define my own exception, and I have to raise some
exception that rails know about. I cant find anything about the
possible exceptions i could raise. Maybe Im just way off and not even
on the right track here, I have no clue at this point.
Nicholas Seckar wrote:
>Hi Joe,
>
>A transaction is rolled back when an exception is thrown beyond
>the .transaction block. You''ll often see:
>
>@a = A.new ...
>@b = B.new ...
>@b.a = @a
>begin
> transaction do
> raise SomeError unless a.save && b.save
> notice "Save successful" # records have been saved, show
success page
> redirect_to :show ...
> end
>rescue SomeError # rollback done
> notice "Save failed" # show error message
> # assuming postback, render the form again so user can fix input.
>end
>
>
>
zipError needs to be an actual error class. You can use one of Ruby''s build in classes, such as ArgumentError, or one of ActiveRecord''s such as RecordNotFound error, or you can add your own. class SaveFailed < Exception end begin raise SaveFailed rescue SaveFailed puts "caught save failed error" end Alternatively, you can use a blank raise, with will raise a RuntimeError.
I was curious about how much of an operation should be wrapped in a
transaction.
Say I had something like
list = []
objects.each{ |o| list << o.process; o.destroy}
record.content = list.join
record.save
If I wanted to ensure that the entire process took place, would I wrap the
whole thing in a transaction? Further, does a transaction only roll back the
state if an exception is cast? If so, should one use
''record.save!'' in this
case?
Also, does the normal transaction just rely on the database, where as the
object transaction depends on binding the state of the objects beforehand?
Just trying to make sure I know what''s going on before I rely on them
;)
.adam sanderson
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails