2009-09-30 19 views
16

ActiveRecord tiene unos pocos métodos de devolución de llamada diferentes utilizados para simplificar la lógica del modelo. Por ejemplo, los métodos after_find y before_create.¿Por qué las devoluciones de llamada de ActiveRecord requieren variables de instancia o métodos de instancia con el prefijo selfword?

Considere este ejemplo de código:

class ExternalPrintingCard < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :ph_user 

    after_create :change_pin 

    def change_pin 
    self.user.randomize_printer_pin 
    end 

    def after_find 
    return if self.card_status == false 
    self.card_status = false if self.is_used_up? 
    self.card_status = false if self.is_expired? 
    self.save! 
    end 
end 

Si quito todos los self prefijos de las variables de instancia o métodos de instancia, serán llamados estos 2 devoluciones de llamada, pero es como si fueran variables locales dentro de estas devolución de llamada métodos.

Esta variable de instancia (card_status), métodos de instancia (save!, is_used_up? y is_expired?) y asociación (user) funcionaba bien fuera de estos 2 métodos de devolución de llamada sin el self prefijo. El código de muestra en la documentación de Rails para métodos de devolución de llamada (métodos de instancia), parece usar siempre el prefijo self aunque está llamando a variables o métodos de instancia, que por derecho son accesibles normalmente sin el prefijo self.

Espero que alguien con una mejor comprensión de las devoluciones de llamada de ActiveRecord pueda ayudar a arrojar luz sobre este comportamiento.

Saludos

Respuesta

14

Técnicamente sólo tiene que utilizar el auto frente a los métodos de asignación. Esto es necesario para diferenciar entre un método de instancia con seguimiento = y una asignación a una variable local.

+5

Consulte este artículo de Thoughtbot para obtener más información: http://robots.thoughtbot.com/post/185504560/to-self-or-not-to-self –

+0

Otro artículo que lo explica http: //www.rubyfleebie. com/use-self-explicitly / –

1

Nasmorn es correcto.

ActiveRecord :: Base colocó todos los nombres de columna dentro de la variable de instancia @attributes (Hash) y creó métodos de instancia de acceso para esos nombres de columna.

Por ejemplo:

card_status es una columna en la tabla external_printing_cards, que tendrá métodos de acceso con el nombre card_status y card_status=

Desde rubí definición variable local es dinámica, la línea

def after_find 
    .... 
    card_status = false if self.is_used_up? 
    .... 
end 

significará que estamos definiendo y asignando a una variable local card_status en lugar del método de instancia card_status=

El artículo publicado por Peer Allan brinda más explicaciones al respecto.

Cuestiones relacionadas