# Optimistic Locking in Controllers: Best practice?

**URL:** <https://discuss.rubyonrails.org/t/optimistic-locking-in-controllers-best-practice/14309>\
**Category:** rubyonrails-talk\
**Created:** [June 12, 2007, 11:37am UTC](https://discuss.rubyonrails.org/t/optimistic-locking-in-controllers-best-practice/14309 "2007-06-12T11:37:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Christoph\_Olszowka2](https://avatars.discourse-cdn.com/v4/letter/c/87869e/32.png) [@Christoph\_Olszowka2](https://discuss.rubyonrails.org/u/Christoph_Olszowka2)\
**Post date:** [June 12, 2007, 11:37am UTC](https://discuss.rubyonrails.org/t/optimistic-locking-in-controllers-best-practice/14309/1 "2007-06-12T11:37:45Z")

</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 Olszowka

---

<div class="post-metadata">

**Author:** ![Jacob\_Atzen](https://avatars.discourse-cdn.com/v4/letter/j/73ab20/32.png) [@Jacob\_Atzen](https://discuss.rubyonrails.org/u/Jacob_Atzen)\
**Post date:** [June 12, 2007, 2:13pm UTC](https://discuss.rubyonrails.org/t/optimistic-locking-in-controllers-best-practice/14309/2 "2007-06-12T14:13:05Z")

</div>

Christoph Olszowka 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.

---

<div class="post-metadata">

**Author:** ![Christoph\_Olszowka2](https://avatars.discourse-cdn.com/v4/letter/c/87869e/32.png) [@Christoph\_Olszowka2](https://discuss.rubyonrails.org/u/Christoph_Olszowka2)\
**Post date:** [June 12, 2007, 7:47pm UTC](https://discuss.rubyonrails.org/t/optimistic-locking-in-controllers-best-practice/14309/3 "2007-06-12T19:47:40Z")

</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:** ![Alexey\_Verkhovsky](https://avatars.discourse-cdn.com/v4/letter/a/3ec8ea/32.png) [@Alexey\_Verkhovsky](https://discuss.rubyonrails.org/u/Alexey_Verkhovsky)\
**Post date:** [June 12, 2007, 9:11pm UTC](https://discuss.rubyonrails.org/t/optimistic-locking-in-controllers-best-practice/14309/4 "2007-06-12T21:11:18Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Nick\_Sieger](https://avatars.discourse-cdn.com/v4/letter/n/c57346/32.png) [@Nick\_Sieger](https://discuss.rubyonrails.org/u/Nick_Sieger)\
**Post date:** [June 13, 2007, 1:51am UTC](https://discuss.rubyonrails.org/t/optimistic-locking-in-controllers-best-practice/14309/5 "2007-06-13T01:51:33Z")

</div>

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
