Single user editing and commit feature

Hi all,

I need to develop an Rails app where all changes should be done on a "shadow copy" of the data and then committed all at once. Only one user may edit the data at any given time. Other users should not see the changes until the commit is done. Before commiting the changes, the user should be able to review a summary of the changes made since the editing began.

These are basically ACID requirements, but the fact that the changes will span multiple HTTP requests -and potentially multiple editing sessions spread out over several days - I'm not sure that database transactions are the best solution (or even feasible)

There is not a huge amount of data involved, so copying the entire database when a user enters edit mode is a possibility.

Does anybody have any input on this?

Hi all,

I need to develop an Rails app where all changes should be done on a "shadow copy" of the data and then committed all at once. Only one
user may edit the data at any given time. Other users should not see the changes until the commit is done. Before commiting the changes, the
user should be able to review a summary of the changes made since the
editing began.

Perhaps acts_as_versioned could be subverted for this ?

Fred

I am assuming that ALL data needs to be locked. That is, every row in every table is locked.

A simple way to do it would be to have a check_outs table. It would only ever have one row, and it would have a user_id column.

If nobody had anything checked out, then user_id would be nil.

Upon checkout the current user's user_id would be stored in this table.

You can then add a validation to every model (except the CheckOut model) that disallows the model from being updated except when current_user.id == CheckOut.user_id.

Does that make sense?

Paul

Thank you both for helping out, I really appreciate it.

Fred: I think acts_as_versioned could be helpful in a couple of ways here. It could implement the snapshot which the read-only users will see while someone else is in edit mode. Basically it's just a matter of storing a list of all object types and a corresponding version number.

The revision history per object which acts_as_versioned provides can perhaps be used to keep track of changes made by a user since entering the edit session. Finally, the revert_to method could be used to rollback changes if the user in edit mode decides not to commit anything.

Paul: Yes, all data needs to be locked. The check_outs table is a good idea for implementing the concurrency lock, I'll probably use it!

I would also need acts_as_paranoid to be able to rollback deletes, and by the looks of it, also do some hacking of both these plugins: http://ward.vandewege.net/blog/2007/02/27/116/

The more I think about it, this journalling alternative feels kinda messy and risky. I would really prefer a solution where edits didn't affect the real data until the user commits.

The extreme case scares me: the user enters edit mode, deletes everything and creates a completely different set of objects, and finally decides not to commit... :-/

Another motivator for another solution (which I accidently omitted yesterday) is that external systems will read the data using SQL and I really don't want them to be aware of any journalling and snapshot stuff.

Does anybody have *any* alternative approaches to this problem? Just thinking out loud - would it be possible to temporarily "short circuit" AR to only operate on in-memory objects for example? (The changes made during an edit session can be considered expendable until committed)

I'm giving this thread a last chance. I feel stuck and would really appreciate any hints on how to solve this.

Basically what I'm looking for is the semantics of a full database copy for the duration of the edit session, without having to, ermm.. copy the database.

I'm giving this thread a last chance. I feel stuck and would really appreciate any hints on how to solve this.

Don't save changes at all, just persist them in something like
memcached until ready? it's definitely not trivial (for example do you
need to worry if the changes made during the edit session don't apply
any more (eg user edits records a,b,c. while they are editing b gets
deleted. do you still apply remaining changes to a & c ?)

Fred

Frederick Cheung wrote:

Don't save changes at all, just persist them in something like memcached until ready?

Thanks again for your input, Fred. Yeah.. Working with in-memory objects during the edit session is probably the way to go. I'll make an attempt to overload ActiveRecord save() etc to see what happens.

do you need to worry if the changes made during the edit session don't apply any more (eg user edits records a,b,c. while they are editing b gets deleted. do you still apply remaining changes to a & c ?)

No, I don't have to deal with that since two users cannot be in edit mode simultaneously.