Это проблема гонки в Rails 3? - PullRequest
1 голос
/ 18 января 2012

В основном у меня есть эта Пользовательская модель, которая имеет определенные атрибуты, скажем, 'здоровье', и другую Битву модель, которая записывает всю битву между Пользователями.Пользователи могут сражаться друг с другом, и некоторая вероятность определит, кто победит.Оба потеряют здоровье после боя.

Итак, в контроллере Битва , действие "СОЗДАТЬ", которое я сделал,

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

В битве 1013* модель,

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

, чтобы получить новое значение здоровья после Битвы.Однако значение, которое я получил, - это старое значение здоровья (значение здоровья до битвы).

Кто-нибудь сталкивался с такой проблемой раньше ???


ОБНОВЛЕНИЕ

Я просто добавляю

current_user.reload

перед строкой

new_user_health = current_user.health

, и это работает.Задача решена.Спасибо!

1 Ответ

4 голосов
/ 18 января 2012

Похоже, вы получаете current_user, затем обновляете battle.user и ожидаете, что current_user автоматически получит обновленные значения. Этот тип вещей возможен при использовании Rails ' Identity Map , но есть некоторые предостережения, о которых вы захотите прочитать вначале.

Проблема в том, что, хотя два объекта поддерживаются одними и теми же данными в базе данных, у вас есть два объекта в памяти. Чтобы обновить информацию, вы можете позвонить current_user.reload.

Как примечание: это не будет классифицироваться как состояние гонки, потому что вы не используете более одного процесса для изменения / чтения данных. В этом примере вы читаете данные, а затем обновляете данные другого объекта в памяти. Состояние гонки может возникнуть, если вы используете два потока для одновременного доступа к одной и той же информации.

Кроме того, вы должны использовать battle.user, а не battle.User, как Уэйн упоминал в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...