2012-01-18 30 views
1

基本上我有这个用户模型具有一定的属性说“健康”和另一模型,记录所有用户之间的斗争。用户可以互相争斗,有些概率会决定谁胜出。两人在战斗后都会失去生命。这是Rails 3中的竞态条件问题吗?

所以在战役控制器, '创建' 动作我做了,

@battle = Battle.attempt current_user.id, opponent.id 

模型,

def self.attempt current_user.id, opponent_id 

    battle = Battle.new({:user_id => current_user.id, :opponent_id => opponent_id}) 

    # all the math calculation here 
    ... 

    # Update Health 
    ... 
    battle.User.health = new_health 
    battle.User.save 
    battle.save 

    return battle 

end 

回到控制器,我做...

new_user_health = current_user.health 

在战斗结束后获得新的健康价值。然而,我得到的价值是旧的健康价值(战前的健康价值)。

有没有人在之前遇到过这种问题?


UPDATE

我行

new_user_health = current_user.health 

和工作前加

current_user.reload 

。问题解决了。谢谢!

+1

我_think_这是你正在面对的:http://stackoverflow.com/questions/5519741/how-can-i-know-when-to-refresh-my-model-object-in-rails – sarnold 2012-01-18 02:28:41

+0

哪部分令人困惑?雅这是实际的代码,但我只突出主要的东西 – 2012-01-18 02:28:50

+0

我编辑代码升技,现在不那么混乱? – 2012-01-18 02:30:46

回答

4

看起来您正在获得current_user,然后更新battle.user,然后预计current_user会自动更新值。这种类型的事情可以使用Rails'Identity Map,但是有一些注意事项需要先阅读。

的问题是,即使两个对象在数据库中的相同数据的支持下,你必须在内存中的两个对象。要刷新信息,您可以拨打current_user.reload

作为一个侧面说明,这不会因为你不使用多个进程修改/读取数据分类的竞争条件。在本例中,您正在读取数据,然后更新内存中不同对象上的数据。如果您使用两个线程同时访问相同的信息,则可能会发生竞态条件。

此外,你应该使用battle.user,而不是像韦恩在评论中提到的battle.User

+0

这就是我说的:)虽然你的时间更长。 (哦,如果我有镍......)+1拼写它全部。 – 2012-01-18 03:08:54