2010-09-29 7 views
8

Me di cuenta de que Rails no desencadena la devolución de llamada after_initialize cuando se pasa el símbolo de devolución de llamada como entrada.ActiveRecord: No llama a after_initialize cuando se pasa el nombre del método como un símbolo

El código siguiente no funciona.

class User < ActiveRecord::Base 
    after_initialize :init_data 

    def init_data 
    puts "In init_data" 
    end 

end 

El siguiente código funciona.

class User < ActiveRecord::Base 

    def after_initialize 
    init_data 
    end 

    def init_data 
    puts "In init_data" 
    end 
end 

¿Alguien puede explicar este comportamiento?

Nota 1

El ActiveRecord documentation dice lo siguiente acerca de 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. 

Aunque se afirma que after_initialize requiere la implementación explícita, creo que la segunda frase en el párrafo anterior ambigua, es decir, In that case, all of the callback types will be called. ¿Qué es all of the call back types?

El ejemplo de código en la documentación tiene un ejemplo que no utiliza la aplicación explícita:

after_initialize EncryptionWrapper.new 

Respuesta

7

De acuerdo con la documentation, no se puede utilizar la macro métodos de clase al estilo de los after_initialize o after_find devoluciones de llamada:

Las devoluciones de llamada after_initialize y after_find son un poco diferentes de las otras. No tienen contraseñas before_ * , y la única forma de registrarlas es definiéndolas como métodos regulares. Si intenta registrar after_initialize o after_find utilizando los métodos de clase de macro , simplemente se ignorarán. Este comportamiento se debe a razones de rendimiento , ya after_initialize y after_find ambos serán llamados para cada registro que se encuentra en la base de datos, desacelerando significativamente los consultas.

En resumen, hay que definir un método after_initialize ejemplo:

class User < ActiveRecord::Base 

    def after_initialize 
    do_stuff 
    end 

end 
0

Estoy bastante seguro de que los métodos invocados por el símbolo necesitan ser protegidos o privada.

Editar: Sí, aquí está el Rails 3 documentation:

El método de devoluciones de llamada de referencia de trabajo mediante la especificación de un método protegido o privado disponible en el objeto

+0

Traté de hacer mi método de devolución de llamada privada, y todavía tiene el mismo comportamiento. –

Cuestiones relacionadas