Rails 3, сбитый с толку 'before_create: some_method' ... КОГДА some_method делает свое дело? - PullRequest
0 голосов
/ 04 февраля 2011

у нас есть помощник модели (используемый несколькими разными моделями) с именем set_guids, который устанавливает self.theguid в случайную строку. Давно пользуясь им, мы знаем, что это работает.

в новой модели «Блюдо», которую мы создали, у нас есть

before_create :set_guids    (NOTE: no other before/after/validation, just this)

def do_meat_dish
  ( this is invoked by @somemeat.do_meat_dish in the Dish contoller )
  ( it manipulated the @somemeat object using self.this and self.that, works fine)

  ( THEN sometimes it creates a new object of SAME MODEL type )
  ( which is handled differently) 
    @veggie = Dish.new
    @veggie.do_veggie_dish
end

def do_veggie_dish
  recipe_str = "add the XXXX to water"
  recipe_str.gsub!("XXXX", self.theguid)  *** the PROBLEM: self.theguid is nil 
end

как только мы выполним veggie = Dish.new, не следует ли инициализировать veggie.theguid?

Обратите внимание, что мы не сохранили новый объект еще ... но before_create должен был все же сделать свое дело, верно?

это как-то связано с созданием нового экземпляра модели внутри метода для той же модели?

это что-то с использованием @ для переменных?

Дополнительное примечание: если мы закомментируем строку, пытаясь получить доступ к self.theguid, все остальное работает нормально ... это ТОЛЬКО значение (предположительно), установленное before_create set_guids, равным nil, а не guid.

1 Ответ

2 голосов
/ 04 февраля 2011

before_create вызывается только перед первым сохранением объекта в базе данных. Вот почему вы получаете nil.

Я предлагаю вместо этого использовать after_initialize callback. Однако будьте осторожны, поскольку after_initialize будет вызываться всякий раз, когда документ новый или загружается из БД, таким образом вы будете получать новые направляющие каждый раз, когда получаете документ, а это не то, что вам нужно. Поэтому я предлагаю вам сделать что-то вроде:

def set_guids 
  return unless theguid.nil?
  .....
end

В качестве другого решения, если вы не хотите изменять обратный вызов after_create выше, вы можете сделать что-то вроде:

def theguid
  super || set_guids
end

Это должно отпустить и тебя.

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