Base.save, обратные вызовы и наблюдатели - PullRequest
0 голосов
/ 20 июля 2011

Допустим, у нас есть модель Champ со следующими атрибутами, все со значениями по умолчанию nil: winner, lost, coach, awesome, should_watch.

Предположим, что выполняются две отдельные операции: (1) создается новая запись и (2) вызывается c.the_winner для экземпляра Champ.

Исходя из моего ложного кода и наблюдателя в модели, какие значения сохраняются в БД для этих двух сценариев? То, что я пытаюсь понять, - это принципы работы обратных вызовов в контексте операции Base.save, и когда и когда операция Base.save должна вызываться более одного раза, чтобы зафиксировать изменения.

class Champ

  def the_winner
    self.winner = 'me'
    self.save
  end

  def the_loser
    self.loser = 'you'
  end

  def the_coach
    self.coach = 'Lt Wiggles'
  end

  def awesome_game(awesome_or_not=false)
    self.awesome = awesome_or_not
  end

  def should_watch_it(should=false)
    self.should_watch = should
  end

end

class ChampObserver

  def after_update(c)
    c.the_loser
  end

  def after_create(c)
    c.the_coach
  end

  def before_create(c)
    c.awesome_game(true)
    c.should_watch_it(true) if c.awesome_game
  end

конец

1 Ответ

1 голос
/ 20 июля 2011

В вашем примере, если вы вызвали champ.winner для нового и неизмененного экземпляра Champ, экземпляр Champ будет зафиксирован в БД и будет выглядеть в базе данных следующим образом:

winner: 'me'
awesome: true
should_watch: true
loser: nil
coach: nil

Обратный вызов after_create будет вызываться, если это новая запись, а если нет, то обратный вызов after_update будет (поэтому loser будет нулевым, если экземпляр был новым). Однако, поскольку они просто вызывают метод установки в экземпляре, они будут только обновлять экземпляр и не будут вносить больше изменений в базу данных.

Вы можете использовать update_attribute в методах наблюдателя или модели, чтобы зафиксировать изменение, но если вам действительно не нужно иметь запись в базе данных, а затем обновить ее, это расточительно. В этом примере, если вы хотите, чтобы эти обратные вызовы фактически устанавливали loser и coach в базе данных, было бы более эффективно использовать before_save и before_create.

На сайте гидов Rails есть хороший обзор обратных вызовов здесь , если вы еще не читали его.

...