Hi All, I''m having some trouble deciding when and how to implement optimistic locking. Let''s say I have a multiuser Rails app, and let''s say it stores, among other things "vital" customer information. The standard methods created by the Rails generate scaffold script look like this: def edit @customer = Customer.find(params[:id]) end def update @customer = Customer.find(params[:id]) if @customer.update_attributes(params[:customer]) flash[:notice] = ''Customer was successfully updated.'' redirect_to :action => ''show'', :id => @customer else render :action => ''edit'' end end What if I want to guard against 2 people simultaneously updating the same customer record? How would I go about doing this? I can''t find any examples online, and I''m a bit lost. Thanks, : ) Jason
> What if I want to guard against 2 people simultaneously updating > the same customer record? How would I go about doing this? I can''t > find any examples online, and I''m a bit lost.Well, first of all, you need a lock_version column in your model (table) (or override it with the "set_locking_column" method). If a record has been changed by someone else, Rails will throw a StaleObjectError, you need to trap this error and handle it appropriately (present the user with a dialog confirming to update the record anyway or cancel it). It''s up to you to find a way to handle the error. Best regards Peter De Berdt
Peter De Berdt wrote:>> What if I want to guard against 2 people simultaneously updating >> the same customer record? How would I go about doing this? I can''t >> find any examples online, and I''m a bit lost. > > Well, first of all, you need a lock_version column in your model > (table) (or override it with the "set_locking_column" method). If a > record has been changed by someone else, Rails will throw a > StaleObjectError, you need to trap this error and handle it > appropriately (present the user with a dialog confirming to update > the record anyway or cancel it). It''s up to you to find a way to > handle the error. > > Best regards > > Peter De BerdtThanks Peter, but in the scaffold generated CRUD code, the model state is lost between the "edit" and "update" calls. -- the StaleObjectError will never be thrown. : ) Jason -- Posted via http://www.ruby-forum.com/.
Jason Tuttle wrote:> Hi All, > > I''m having some trouble deciding when and how to implement optimistic > locking. > > Let''s say I have a multiuser Rails app, and let''s say it stores, > among other things "vital" customer information. > > The standard methods created by the Rails generate scaffold script > look like this: > > def edit > @customer = Customer.find(params[:id]) > end > > def update > @customer = Customer.find(params[:id]) > if @customer.update_attributes(params[:customer]) > flash[:notice] = ''Customer was successfully updated.'' > redirect_to :action => ''show'', :id => @customer > else > render :action => ''edit'' > end > end > > What if I want to guard against 2 people simultaneously updating the > same customer record? How would I go about doing this? I can''t find > any examples online, and I''m a bit lost. > > Thanks, > > : ) > > JasonThe more I think about it, there doesn''t seem to be a way to take advantage of Active Record''s optimistic locking when using the standard scaffold generated CRUD approach because the model state is lost between the call to "edit" and the subsequent call to "update". -- The ActiveRecord::StaleObjectError will never be thrown. Do you have to manually track the value of the lock_version column? There must be a more elegant solution. I must be missing something. I just can''t figure out what. - Jason -- Posted via http://www.ruby-forum.com/.
On Tuesday, May 09, 2006, at 8:18 PM, Jason Tuttle wrote:>Jason Tuttle wrote: >> Hi All, >> >> I''m having some trouble deciding when and how to implement optimistic >> locking. >> >> Let''s say I have a multiuser Rails app, and let''s say it stores, >> among other things "vital" customer information. >> >> The standard methods created by the Rails generate scaffold script >> look like this: >> >> def edit >> @customer = Customer.find(params[:id]) >> end >> >> def update >> @customer = Customer.find(params[:id]) >> if @customer.update_attributes(params[:customer]) >> flash[:notice] = ''Customer was successfully updated.'' >> redirect_to :action => ''show'', :id => @customer >> else >> render :action => ''edit'' >> end >> end >> >> What if I want to guard against 2 people simultaneously updating the >> same customer record? How would I go about doing this? I can''t find >> any examples online, and I''m a bit lost. >> >> Thanks, >> >> : ) >> >> Jason > >The more I think about it, there doesn''t seem to be a way to take >advantage of Active Record''s optimistic locking when using the standard >scaffold generated CRUD approach because the model state is lost between >the call to "edit" and the subsequent call to "update". -- The >ActiveRecord::StaleObjectError will never be thrown. > >Do you have to manually track the value of the lock_version column? > >There must be a more elegant solution. > >I must be missing something. I just can''t figure out what. > >- Jason > >-- >Posted via http://www.ruby-forum.com/. >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/railsIt works. I think it puts a hidden text field with the value of the lock_version in the form. When you go to save it, it compares the value to the one in the database. If the one in the database is different, then someone has modified the record. Once saved, the value is incremented. So the state of the record is retained. I think AR is smart enough to know what to do with this without adding additional code, which is why they call it a ''magic'' column. _Kevin -- Posted with http://DevLists.com. Sign up and save your mailbox.
On May 9, 2006, at 11:18 AM, Jason Tuttle wrote:> The more I think about it, there doesn''t seem to be a way to take > advantage of Active Record''s optimistic locking when using the > standard > scaffold generated CRUD approach because the model state is lost > between > the call to "edit" and the subsequent call to "update". -- The > ActiveRecord::StaleObjectError will never be thrown. > > Do you have to manually track the value of the lock_version column?Yes.> There must be a more elegant solution.Wrap up the lock_version handling by passing it in session, crypted form param, or similar.> I must be missing something. I just can''t figure out what.A well-tested patch? :) Michael Schuerig did quite a bit of work on an alternate scaffolding toolset that includes conflict resolution. See his Boilerplate lib: http://www.schuerig.de/michael/boilerplate/ Best, jeremy
Kevin Olbrich wrote:> On Tuesday, May 09, 2006, at 8:18 PM, Jason Tuttle wrote: >>> look like this: >>> else >>> : ) >> >>Rails@lists.rubyonrails.org >>http://lists.rubyonrails.org/mailman/listinfo/rails > > It works. I think it puts a hidden text field with the value of the > lock_version in the form. When you go to save it, it compares the value > to the one in the database. If the one in the database is different, > then someone has modified the record. Once saved, the value is > incremented. > > So the state of the record is retained. I think AR is smart enough to > know what to do with this without adding additional code, which is why > they call it a ''magic'' column. > > _KevinHi Kevin, I just double checked. -- There doesn''t seem to bee any hidden field. - Jason -- Posted via http://www.ruby-forum.com/.
Jeremy Kemper wrote:> On May 9, 2006, at 11:18 AM, Jason Tuttle wrote: >> The more I think about it, there doesn''t seem to be a way to take >> advantage of Active Record''s optimistic locking when using the >> standard >> scaffold generated CRUD approach because the model state is lost >> between >> the call to "edit" and the subsequent call to "update". -- The >> ActiveRecord::StaleObjectError will never be thrown. >> >> Do you have to manually track the value of the lock_version column? > > Yes. > >> There must be a more elegant solution. > > Wrap up the lock_version handling by passing it in session, crypted > form param, or similar. > >> I must be missing something. I just can''t figure out what. > > A well-tested patch? :) > > Michael Schuerig did quite a bit of work on an alternate scaffolding > toolset that includes conflict resolution. See his Boilerplate lib: > http://www.schuerig.de/michael/boilerplate/ > > Best, > jeremyThanks Jeremy. -- I''m off to check out Boilerplate lib right now. - Jason -- Posted via http://www.ruby-forum.com/.
Maybe Matching Threads
- Implementing Optimistic Offline Lock - How ?
- proper way to ensure atomic model changes
- Rename lock_version field?
- [PATCH server] Fixed db-omatic so it doesn't die due to an unhandled ActiveRecord::StaleObjectError exception.
- Optimistic Locking Enhancements: Gem or Core?