ActiveRecord:当方法名称作为符号传递时,不调用after_initialize

Har*_*tty 9 activerecord ruby-on-rails

我注意到after_initialize当回调符号作为输入传递时,Rails不会触发回调.

下面的代码不起作用.

class User < ActiveRecord::Base
  after_initialize :init_data

  def init_data
    puts "In init_data"
  end

end
Run Code Online (Sandbox Code Playgroud)

以下代码有效.

class User < ActiveRecord::Base

  def after_initialize 
    init_data
  end

  def init_data
    puts "In init_data"
  end
end
Run Code Online (Sandbox Code Playgroud)

有人可以解释这种行为吗?

注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. 
Run Code Online (Sandbox Code Playgroud)

虽然有人说After_initialize需要明确实现,但我发现上段中的第二句含糊不清,即In that case, all of the callback types will be called.什么是all of the call back types

文档中的代码示例有一个不使用显式实现的示例:

after_initialize EncryptionWrapper.new
Run Code Online (Sandbox Code Playgroud)

tjw*_*ace 7

根据文档,您不能使用宏样式类方法after_initializeafter_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
Run Code Online (Sandbox Code Playgroud)