Ruby on rails 3.2 在保存时防止ActiveRecord竞争

Ruby on rails 3.2 在保存时防止ActiveRecord竞争,ruby-on-rails-3.2,race-condition,Ruby On Rails 3.2,Race Condition,简称: 在RubyonRails中保存ActiveRecord对象时,如何防止竞争条件?或者,如果检测到竞争,是否至少有一种方法可以获得错误 长: 假设我们有这个模型 class Game < ActiveRecord::Base belongs_to :current_user, :class_name => "User", :foreign_key => "current_user_id" belongs_to :other_u

简称:

在RubyonRails中保存ActiveRecord对象时,如何防止竞争条件?或者,如果检测到竞争,是否至少有一种方法可以获得错误

长:

假设我们有这个模型

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
类游戏“用户”,
:foreign\u key=>“当前用户\u id”
属于:其他用户,:class\u name=>“用户”,
:foreign\u key=>“其他用户\u id
结束
在控制器中创建游戏时,我希望找到第一个游戏,其中:other_user_id为nil,将其设置为尝试创建游戏的用户,然后保存更新的游戏。如果找不到此类游戏,请创建一个新游戏,询问用户为当前_用户

我在ActiveRecord上的文档中找不到任何显示如何在保存更新的游戏时防止竞争的内容,即用户b可以在用户a找到游戏后但在他们保存到数据库之前找到空游戏并保存到数据库中。如果有,我在唯一性验证上读到的内容似乎需要在数据库级别修复此问题


提前感谢!

当然,我没有完全阅读rails指南。在这一部分中,您基本上希望使用乐观锁定。这是通过在游戏中使用lock\u version列来实现的。因此,在迁移中添加以下内容:

 class AddLockedVersionToGames < ActiveRecord::Migration
   def changes
     add_column :games, :lock_version, :integer, :default => 0
   end
 end
  def self.add_user_to_game(current_user)
    game = Game.find_by_other_user(nil)
    if game
      game.other_user = current_user
    else
      game = Game.new(current_user: current_user)
    end
    game.save
  rescue ActiveRecord::StaleObjectError
    game = Game.new(current_user: current_user)
    game.save
  end