canceling a set of actions on an obj and its associations - best approach?

I have a "dialog" type page for the user to update a set of conditions on an object. These Condition objects are associated with the parent obj thru an association. The page lets them remove existing associations or make new ones.

I want to present Update and Cancel buttons for the user. If the user hits Cancel, I want to discard all of the changes and go back to the original state.

There are several approaches I can think of, but I wanted to hear what others think the best way might be. (BTW - I'm still on Rails 1.2.5, in case there's something groovy in this regard in 2.0... I'm not ready to upgrade yet)... Here's what I've thought of and what to do in case of Cancel:

1) use transactions and rollback - might be the cleanest, but I havent used them yet in rails and I dont know if there are gotchas I'll need to learn about

2) clone or dup the parent object and discard - from my quick reading, I'm not sure the shallow copying copies the associations... and if it does, whether it creates new associated objs or not... and then what it does when I discard

3) track the changes and unwind - pretty messy

As always, any help from the group is much appreciated.

I'm curious how this will flow. can you out line the flow of the application with a little more detail?.

The simplest solution i can think of is to marshal/serialize and backup the model each time it's changed so that you can revert to different versions.

Transactions definitely won't work. First, you'd have to stretch the transaction across HTTP requests, because you'd start the transaction in one action, and then either roll it back in the Cancel action or commit it in the Update action. You never want to allow user interaction inside a transaction because the user might drop dead. Second, I don't even know if you _can_ stretch a trx across requests in Rails.

You might consider looking at the Memento design pattern (I don't know if it's in the Ruby patterns book).


I realize that I left out some missing details to my original post...

1) the user clicks an Update Conditions button to go to the page 2) The user updates the associated list of Conditions by adding new ones or removing existing ones thru a 2 AJAX interactions. Existing Conditions are listed with a UI element that they can click to remove. New Conditions can be added from a menu. So, the user can execute a series of Add or Remove actions while still on the page. 3) the idea was to let them commit the entire set of actions by clicking an Update button or discard the set by clicking a Cancel button

One problem with all of this is that the user can, of course, just click away from the page without using either the Update or Cancel button. So perhaps this UI isnt the best.

But, I'm still curious how people have approached being able to reverse/undo/cancel a set of actions like I've described.

Just to let you know how this all worked out...

I chose to rewrite part of my code so that the addition/removal of these associated objects is not actually done on the model itself until the user commits the changes by clicking the Update button.

Instead, I load up a session variable with an array of refs to the associated objs, manipulate that list (add/removes) while still on the page, then apply the final set to the model. Pretty clean and easy.

Thanks for the responses.