Short:
How do you protect against race conditions on saving ActiveRecord objects in Ruby on Rails? Or is there at least a way to get an error if a race was detected?
Long:
Assume we have this Model
class Game < ActiveRecord::Base
belongs_to :current_user, :class_name => "User",
:foreign_key => "current_user_id"
belongs_to :other_user, :class_name => "User",
:foreign_key => "other_user_id
end
When creating games in the controller I want find the first game where :other_user_id is nil, set it to the user trying to create the game and then save the updated game.If no such game is found, create a new game with the asking user as current_user.
I can’t find anything in the documentation on ActiveRecord that shows how to protect against a race on saving the updated game i.e. user b could come in find the empty game and save to the database after user a has found the game but before they’ve saved to the database. If anything, what I’ve read on uniqueness validations seems like I need to fix this at the database level.
Thanks in advance!
You essentially want optimistic locking. This is enabled by having the lock_version column in game. So in a migration add something along the lines of:
And in the game model: