2009-09-30 7 views
16

ActiveRecord a quelques méthodes de rappel différentes utilisées pour simplifier la logique du modèle. Par exemple after_find et before_create des méthodes.Pourquoi les rappels ActiveRecord requièrent-ils des variables d'instance ou des méthodes d'instance avec préfixe self?

Considérons cet exemple de code:

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 je supprime tous les self préfixes des variables d'instance ou les méthodes d'instance, ces 2 callbacks seront appelés, mais il est comme si elles sont des variables locales à l'intérieur de ces rappel méthodes

Cette variable d'instance (card_status), les méthodes d'instance (save!, is_used_up? et is_expired?) et l'association (user) a bien fonctionné en dehors de ces 2 méthodes de rappel sans le préfixe self.

L'exemple de code dans la documentation de Rails pour les méthodes de rappel (méthodes d'instance) semble toujours utiliser le préfixe self même s'il appelle des variables d'instance ou des méthodes, qui sont normalement accessibles sans le préfixe self normalement.

J'espère que quelqu'un avec une meilleure compréhension des rappels ActiveRecord peut aider à faire la lumière sur ce comportement.

Vive

Répondre

14

Techniquement, vous ne devez utiliser l'auto devant les méthodes d'affectation. Ceci est nécessaire pour différencier une méthode d'instance avec trailing = et une affectation à une variable locale.

+5

Voir cet article de Thoughtbot pour beaucoup de détails: http://robots.thoughtbot.com/post/185504560/to-self-or-not-to-self –

+0

un autre article qui l'explique http: //www.rubyfleebie. com/use-self-explicitement / –

1

Nasmorn est correct.

ActiveRecord :: Base a placé tous les noms de colonne à l'intérieur de la variable d'instance @attributes et a créé des méthodes d'instance d'accesseurs pour ces noms de colonne.

Par exemple:

card_status est une colonne dans la table external_printing_cards, il aura des méthodes accesseurs avec le nom card_status et card_status=

Comme définition variable locale rubis est dynamique, la ligne

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

signifie que nous définissons et affectons à une variable locale card_status plutôt que la méthode d'instance card_status=

L'article que Peer Allan a posté fournit plus d'explications à ce sujet.

Questions connexes