When two people attempt to update the same record near the same time, one of the updates will likely be overwritten. You can solve this problem with optimistic locking.
hmm, it seems kind of hard to try to resolve the confict "behind the scenes" without keeping any additional information about the edits.
i think you can do something like a form with radio buttons to choose between the conflicting field(s), but that won't work in case of 2 concurrent changes to the same field, which brings me back to the manual approach. i'm starting to wonder if there's a better way to resolve these dependencies without additional record-keeping.
@vlad, good point. You would need to store the history of the edits with acts_as_versioned or something so you can compare it with the new edits and see who changed what. Then it would be possible to see the two changes didn't overlap (one changed the price and the other changed the description) so it can be resolved behind the scenes.
Alternatively you could pass the model's attributes in hidden fields in addition to the editable fields. That way you have the last history without using act_as_versioned. That might be messy though.
Ryan, Thanks for this! I have a question for some weird behavior I'm seeing:
In my controller I'm doing a model.reload as you've implemented it, and render a "conflict" action. In the controller, if I 'puts' on any of the model variables before and after the reload, I can see the change, but the form never reflects the change. Doing a 'puts' in the form writes out the pre-update model information.
My form is a bit different in that I'm using a form_tag and :id => model_name, but as I understand it, it should reload the model from the db, correct? I'm missing something simple.
Even it's an old one, it's a great one, and as always with every of my projects you seem to read my mind. Had a problem, found your screencast. Keep on going. Thx.
Good show. Locking can be a real pain to understand and implement!
Sorry this is just a bit off topic just wondering what tab terminal software you are using?
@dudzjosh : I think he's using ITerm
dudzjosh: he's using iTerm
hmm, it seems kind of hard to try to resolve the confict "behind the scenes" without keeping any additional information about the edits.
i think you can do something like a form with radio buttons to choose between the conflicting field(s), but that won't work in case of 2 concurrent changes to the same field, which brings me back to the manual approach. i'm starting to wonder if there's a better way to resolve these dependencies without additional record-keeping.
@vlad, good point. You would need to store the history of the edits with acts_as_versioned or something so you can compare it with the new edits and see who changed what. Then it would be possible to see the two changes didn't overlap (one changed the price and the other changed the description) so it can be resolved behind the scenes.
Alternatively you could pass the model's attributes in hidden fields in addition to the editable fields. That way you have the last history without using act_as_versioned. That might be messy though.
oh, so there's an acts_as_versioned? awesome.
Yep, it's a plugin by Rick Olson:
http://svn.techno-weenie.net/projects/plugins/acts_as_versioned/
Ryan, Thanks for this! I have a question for some weird behavior I'm seeing:
In my controller I'm doing a model.reload as you've implemented it, and render a "conflict" action. In the controller, if I 'puts' on any of the model variables before and after the reload, I can see the change, but the form never reflects the change. Doing a 'puts' in the form writes out the pre-update model information.
My form is a bit different in that I'm using a form_tag and :id => model_name, but as I understand it, it should reload the model from the db, correct? I'm missing something simple.
Thanks in advance for a great site!
Ryan,
Ok, ignore me, found the problem, which is in my model definition.
Sometimes it just helps to talk. ;-)
Even it's an old one, it's a great one, and as always with every of my projects you seem to read my mind. Had a problem, found your screencast. Keep on going. Thx.
Thanks for the great content!
What is it all about?
why not to use retry within rescue block?
how do i use optimistic locking for a model with has_many :others and belongs_to :model, :touch => true?