We learn as we go, we write as we learn.

About michelada.io


By joining forces with your team, we can help with your Ruby on Rails and Javascript work. Or, if it works better for you, we can even become your team! From e-Commerce to Fintech, for years we have helped turning our clients’ great ideas into successful business.

Go to our website for more info.

Tags


Optimistic locking of ActiveRecord models

30th May 2018

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.

David Padilla
AUTHOR

David Padilla

View Comments