# Single user editing and commit feature

**URL:** <https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813>\
**Category:** Rails\
**Created:** [April 15, 2008, 11:53am UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813 "2008-04-15T11:53:21Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 15, 2008, 11:53am UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/1 "2008-04-15T11:53:21Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 15, 2008, 12:01pm UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/2 "2008-04-15T12:01:28Z")

</div>

On 15 Apr 2008, at 10:53, Abigail Headroom wrote:

> editing  
> began.

Perhaps acts\_as\_versioned could be subverted for this ?

Fred

---

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 16, 2008, 5:01am UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/3 "2008-04-16T05:01:16Z")

</div>

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

On Apr 15, 2:53 am, Abigail Headroom \<rails-mailing-l…@andreas-

---

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 16, 2008, 8:27am UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/4 "2008-04-16T08:27:51Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 17, 2008, 9:11am UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/5 "2008-04-17T09:11:21Z")

</div>

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/](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)

---

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 21, 2008, 9:51am UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/6 "2008-04-21T09:51:01Z")

</div>

On 21 Apr 2008, at 07:50, Abigail Headroom wrote:

> 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

---

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 21, 2008, 8:50am UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/7 "2008-04-21T08:50:19Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ahead](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c77e96/32.png) [@ahead](https://www.ruby-forum.com/u/ahead)\
**Post date:** [April 21, 2008, 3:52pm UTC](https://www.ruby-forum.com/t/single-user-editing-and-commit-feature/134813/8 "2008-04-21T15:52:09Z")

</div>

Frederick C. 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.
