ActiveRecord: не вызывает after_initialize, когда имя метода передается как символ - PullRequest
9 голосов
/ 30 сентября 2010

Я заметил, что Rails не запускает обратный вызов after_initialize, когда символ обратного вызова передается в качестве ввода.

Код ниже не работает.

class User < ActiveRecord::Base
  after_initialize :init_data

  def init_data
    puts "In init_data"
  end

end

Код нижеработает.

class User < ActiveRecord::Base

  def after_initialize 
    init_data
  end

  def init_data
    puts "In init_data"
  end
end

Может кто-нибудь объяснить это поведение?

Примечание 1

Документация ActiveRecord говорит следующее оafter_initialize:

Unlike all the other callbacks, after_find and after_initialize will 
only be run if an explicit implementation is defined (def after_find). 
In that case, all of the callback types will be called. 

Хотя и утверждается, что after_initialize требует явной реализации, я нахожу второе предложение в вышеприведенном абзаце неоднозначным, т.е.Пример кода в документации содержит пример, который не использует явную реализацию:

after_initialize EncryptionWrapper.new

Ответы [ 2 ]

7 голосов
/ 09 декабря 2010

Согласно документации нельзя использовать методы класса в стиле макроса для обратных вызовов after_initialize или after_find:

Обратные вызовы after_initialize и after_find являютсянемного отличается от других.У них нет аналогов before_ *, и единственный способ зарегистрировать их - определить их как обычные методы.Если вы попытаетесь зарегистрироваться after_initialize или after_find, используя методы класса в стиле макросов, они будут просто проигнорированы.Такое поведение обусловлено соображениями производительности, так как after_initialize и after_find будут вызываться для каждой записи, найденной в базе данных, что значительно замедляет запросы.

Короче говоря, вы должны определить after_initializeметод экземпляра:

class User < ActiveRecord::Base

  def after_initialize
    do_stuff
  end

end
0 голосов
/ 30 сентября 2010

Я почти уверен, что методы, вызываемые символом, должны быть защищены или закрыты.

Редактировать: Да, вот документация Rails 3 :

Обратные вызовы ссылок на методы работают путем указания защищенного или частного метода, доступного в объекте

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