Did you know that Rails can help avoid data overwrite when multiple users are editing the same record?
Yes, you can use optimistic locking on models, and it turns out it's pretty easy to enable it too.
To be honest, I've never heard about this functionality until recently while browsing the Active Record Basics Guide looking for info on a totally different problem that I had.
When I read about the lock_version
field, I was curious and surprised by what I found.
It basically works like this:
If you add the lock_version
field to any ActiveRecord model, every time that record is saved it will be checked for modifications after the record was loaded.
So, if for some reason the record changed in the database while you were editing it, when you try to save it an ActiveRecord::StaleObjectError
exception will be raised.
Example:
require 'active_record'
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :orders do |t|
t.integer :total
t.string :lock_version
end
end
class Order < ActiveRecord::Base ; end
Order.create
object_1 = Order.find(1)
object_2 = Order.find(1)
object_1.total = 100
object_1.save # Succeeds!
object_2.total = 200
object_2.save # Raises ActiveRecord::StaleObjectError
You can see from the example that both object_1
and object_2
were loaded at the same time.
When you modify and change the first object, it will be saved without any problem and the save
method will return true as expected, but when you try and save the second one (object_2
), the ActiveRecord::StaleObjectError
will be raised because the object has been modified already.
You can read more about this feature directly on its API documentation.
It is worth mentioning that there is a more aggressive way to lock records by using Pessimistic Locking
.
Top comments (0)