# Optimistic Locking in Controllers: Best practice?

**URL:** <https://www.ruby-forum.com/t/optimistic-locking-in-controllers-best-practice/106614>\
**Category:** Rails\
**Created:** [June 12, 2007, 1:38pm UTC](https://www.ruby-forum.com/t/optimistic-locking-in-controllers-best-practice/106614 "2007-06-12T13:38:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Christoph\_O](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ad7895/32.png) [@Christoph\_O](https://www.ruby-forum.com/u/Christoph_O)\
**Post date:** [June 12, 2007, 1:38pm UTC](https://www.ruby-forum.com/t/optimistic-locking-in-controllers-best-practice/106614/1 "2007-06-12T13:38:47Z")

</div>

Hi,

I’ve searched the group archives on this, but could not find anything  
except an unanswered question that results from the same problem I  
encountered, or at least that’s what I guess ([http://groups.google.com/](http://groups.google.com/)  
group/rubyonrails-talk/browse\_thread/thread/d771abdd51e12c8d/  
68d54f84c00fa45a).

The basic theory with locking is: Take two objects, save one of those,  
and saving of the second one will fail. Sounds nice and works very  
well in console, which is being demonstrated in the Rails cookbook  
etc.

BUT: When I want to do such a thing in a controller action it won’t  
work the way it’s supposed to (at least imho), because I am not  
retrieving the object from the form (say “edit”) and re-using it, but  
rather retrieving a new instance by id with a before\_filter get\_user  
or whatever. Now if a second user saves the same object after I  
accessed the form, but before I submit my changes, his changes will be  
overwritten by mine without a StaleObjectError being risen, because  
the lock\_version seems correct.

This really is NOT what I want locking to do for me. My aim is to  
prevent users from submitting forms with outdated data.

So now I came up with the idea of adding a hidden input “lock\_version”  
to my forms and applying this param to my model instance in “update”.  
Now locking will work properly, but this does not seem very clean as  
the user could just manipulate those data or remove the lock\_version  
entirely, which would skip the locking protection.

Is there something like a “best practice” for implementing such a  
locking behavior in controllers? I’ve been thinking about checking if  
the lock\_version is given in params with a before\_filter or something,  
as well as storing instances of the model in session, but as I  
mentioned, this does not seem pretty clean code to me, so now I am  
hoping for someone who already thought more about this topic to help  
me out 🙂

Thanks in advance and greetings,  
Christoph O.

---

<div class="post-metadata">

**Author:** ![Christoph\_O](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ad7895/32.png) [@Christoph\_O](https://www.ruby-forum.com/u/Christoph_O)\
**Post date:** [June 12, 2007, 4:13pm UTC](https://www.ruby-forum.com/t/optimistic-locking-in-controllers-best-practice/106614/2 "2007-06-12T16:13:36Z")

</div>

Christoph O. wrote:

> So now I came up with the idea of adding a hidden input “lock\_version”  
> to my forms and applying this param to my model instance in “update”.  
> Now locking will work properly, but this does not seem very clean as  
> the user could just manipulate those data or remove the lock\_version  
> entirely, which would skip the locking protection.

If your users wants to corrupt your data, optimistic locking is not  
going to solve the problem for you. Optimistic locking is not a security  
mechanism. Even if you did ensure that a user could not save stale data  
the user could just refetch the object from the database and update it  
again with whatever changes desired.

If you really, really want to ensure that no user ever submits stale  
data you could use a hash for comparison and record a new hash value in  
the record on each update. In that case you can ensure that no-one will  
ever be able to submit a stale record.

–  
Cheers,

- Jacob A.

---

<div class="post-metadata">

**Author:** ![Christoph\_O](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ad7895/32.png) [@Christoph\_O](https://www.ruby-forum.com/u/Christoph_O)\
**Post date:** [June 12, 2007, 9:48pm UTC](https://www.ruby-forum.com/t/optimistic-locking-in-controllers-best-practice/106614/3 "2007-06-12T21:48:17Z")

</div>

Hi Jacob,

I know that this kind of locking won’t give me perfect safety, but  
I am rather aiming for some user convenience anyway. The main  
purpose should be to tell the user “Whoops, someone was quicker  
than you!” and throw him back to the page, rather than ensuring  
really perfect data consistency.

Greetings  
Christoph

---

<div class="post-metadata">

**Author:** ![Christoph\_O](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ad7895/32.png) [@Christoph\_O](https://www.ruby-forum.com/u/Christoph_O)\
**Post date:** [June 13, 2007, 3:52am UTC](https://www.ruby-forum.com/t/optimistic-locking-in-controllers-best-practice/106614/4 "2007-06-13T03:52:03Z")

</div>

On 6/12/07, Christoph O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi,
> 
> So now I came up with the idea of adding a hidden input “lock\_version”  
> to my forms and applying this param to my model instance in “update”.  
> Now locking will work properly, but this does not seem very clean as  
> the user could just manipulate those data or remove the lock\_version  
> entirely, which would skip the locking protection.

Given the amount of protection desired (convenience only, not  
security), this seems like a perfectly reasonable approach to me, and  
it’s much better than storing it in the session because it makes the  
post stateless.

/Nick

---

<div class="post-metadata">

**Author:** ![Christoph\_O](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ad7895/32.png) [@Christoph\_O](https://www.ruby-forum.com/u/Christoph_O)\
**Post date:** [June 12, 2007, 11:12pm UTC](https://www.ruby-forum.com/t/optimistic-locking-in-controllers-best-practice/106614/5 "2007-06-12T23:12:36Z")

</div>

On 6/12/07, Christoph O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> So now I came up with the idea of adding a hidden input “lock\_version”  
> to my forms and applying this param to my model instance in “update”.  
> Now locking will work properly, but this does not seem very clean as  
> the user could just manipulate those data or remove the lock\_version  
> entirely, which would skip the locking protection.

That’s why we have serer-side sessions. Save the lock\_version value  
there. Do not save the entire model object though, storing model  
instances in the session is not just ugly, it’s an almost certain way  
to introduce interesting, unreproducible bugs.

–  
Alex Verkhovsky  
RubyWorks
