Deals with conflicts when they occur by implementing a locking table attribute. It happens in application logic and does not involve database specific mechanism.
Class AddLockVersionToTimesheets < ActiveRecord::Migration
def change
add column :timesheets, :lock_version, :integer, default: 0
end
enddescribe Timesheet do
it "locks optimistically" do
t1 = Timesheet.create
t2 = Timesheet.find t1.id
t1.rate = 250
t2.rate = 200
expect(t1.save).to be_true
expect(t2.save).to raise_error(ActiveRecord::StaleObjectError)
end
end def update
timesheet = Timesheet.find params[:id]
timesheet.update params[:timesheet]
redirect_to timesheets_url, notice: "successful update"
rescue ActiveRecord::StaleObjectError
flash[:alert] = "Timesheet was modified while we were editing it .."
redirect_to [:edit, timesheet]
end
endAssumes the worst in the beginning. Locks at the database level by means of transactions.
Timesheet.transaction do
t = Timesheet.lock.first
t.approved.toggle
t.save!
endSource: (The Rails 4 Way).