#59 Optimistic Locking
Jul 18, 2007 | 7 minutes | Active Record
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.
migrations/011_add_products_lock_version.rb
add_column :products, :lock_version, :integer, :default => 0, :null => false
add_column :products, :lock_version, :integer, :default => 0, :null => false
products_controller.rb
def update
@product = Product.find(params[:id])
if @product.update_attributes(params[:product])
flash[:notice] = "Successfully updated product."
redirect_to product_path(@product)
else
render :action => 'edit'
end
rescue ActiveRecord::StaleObjectError
@product.reload
render :action => 'conflict'
end
def update @product = Product.find(params[:id]) if @product.update_attributes(params[:product]) flash[:notice] = "Successfully updated product." redirect_to product_path(@product) else render :action => 'edit' end rescue ActiveRecord::StaleObjectError @product.reload render :action => 'conflict' end
_form.rhtml
<%= f.hidden_field :lock_version %>
<%= f.hidden_field :lock_version %>
conflict.rhtml
<% title "Edit Product Conflict" %>
Someone edited the product the same time you did. Please re-apply your changes to the product.
<h2>Your Submission:</h2>
<pre>
<% params[:product].each do |name, value| %>
<%=h name.humanize %>: <%=h value %>
<% end %>
</pre>
<h2>Edit Product:</h2>
<% form_for :product, :url => product_path(@product), :html => { :method => :put } do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<%= submit_tag 'Resolve' %>
<% end %>
<% title "Edit Product Conflict" %> Someone edited the product the same time you did. Please re-apply your changes to the product. <h2>Your Submission:</h2> <pre> <% params[:product].each do |name, value| %> <%=h name.humanize %>: <%=h value %> <% end %> </pre> <h2>Edit Product:</h2> <% form_for :product, :url => product_path(@product), :html => { :method => :put } do |f| %> <%= render :partial => 'form', :locals => { :f => f } %> <%= submit_tag 'Resolve' %> <% end %>

