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