Обратный вызов Rails для эквивалента "after_new"
Сейчас я не могу найти способ создания обратного вызова между строками 1 и 2 здесь:
f = Foo.new
f.some_call
f.save!
Есть ли способ имитировать то, что было бы эффективно after_new callback? Сейчас я использую after_initialize, но есть потенциальные проблемы с производительностью при использовании этого, поскольку он запускается для множества разных событий.
Ответы
Ответ 1
Вы можете использовать обратный вызов after_initialize
# app/models/foo.rb
class Foo < ActiveRecord::Base
after_initialize :some_call
def some_call
puts "Who you gonna call?"
end
end
# rails console
> foo = Foo.new # => "Who you gonna call?"
> foo = Foo.first # => "Who you gonna call?"
Остерегайтесь after_initialize
запускается каждый раз, когда ActiveRecord выполняет Foo.new
(вызовы типа new
, find
, first
и т.д.) см. в Rails Guide
Итак, вы, вероятно, хотите что-то вроде этого after_initialize :some_call, :if => :new_record?
# app/models/foo.rb
class Foo < ActiveRecord::Base
after_initialize :some_call, :if => :new_record?
def some_call
puts "Who you gonna call?"
end
end
# rails console
> foo = Foo.new # => "Who you gonna call?"
> foo = Foo.first
Ответ 2
Если это модель Active Record, то after_initialize - это правильный способ обработки обратных вызовов после создания объекта. Сама структура делает определенные предположения о том, как объекты будут создаваться из базы данных. Производительность не должна вызывать беспокойства, если в обратном вызове не запускается какая-то давняя задача, и в этом случае вам, вероятно, придется пересмотреть стратегию.
Если не AR-модель, вы можете создать метод инициализации в своем объекте и поместить там код.
Доступен ряд других обратных вызовов в зависимости от того, что вы хотите сделать, включая after_create (вызывается при создании новой записи).
Ответ 3
Определите конструктор для Foo
и сделайте то, что вам нужно сделать.
Альтернативным решением будет изучение after_initialize
, но это может не делать то, что вы ожидаете.