2009-08-28 8 views
51

Je viens de commencer à apprendre Ruby on Rails et moi avons rencontré le code comme ci-dessous:appels Ruby méthode déclarée dans le corps de la classe

class Post < ActiveRecord::Base 
validates_presence_of :title 
belongs_to :user 
end 

Il y a deux appels de méthode à l'intérieur du corps de la classe. J'ai eu du mal à trouver une documentation ruby ​​que décrit comment les appels de méthode à l'intérieur d'un corps d'une classe (mais en dehors de toute méthode) fonctionnent. Tous les livres que j'ai, seulement décrire comment définir les méthodes de classe et d'instance et comment les appeler à partir d'autres méthodes.

Les questions que j'ai sont: Comment et quand ces méthodes sont-elles appelées? Comment sont-ils définis? Sont-ils mixins définis dans un module d'enregistrement actif?

Répondre

3

Ce que vous voyez sont des méthodes de niveau classe pour un objet ActiveRecord. Pour écrire vos propres méthodes qui fonctionnent comme cela vous les écrirez comme un plugin et ensuite les inclure dans ActiveRecord en ré-ouvrant la définition de classe. Ruby on Rails guide pour créer un plug-in:

http://guides.rubyonrails.org/plugins.html

comment on pourrait Covers écrire ces méthodes de niveau classe plugin /. C'est un bon document sur la façon de comprendre ce que ces méthodes signifient et comment elles interagissent avec les instances.

+1

Une gemme fonctionne aussi bien. –

11

Re: Comment et quand ces méthodes sont-elles appelées?

[Ils sont appelés lorsque la classe est chargée. Vous pouvez placer un point d'arrêt dans l'une des méthodes et voir qu'il est appelé dans le cadre du projet de démarrage de votre rail.]

Comment sont-ils définis?

[Ce sont des méthodes de classe. Comme il s'agit d'un rubis, ils peuvent être définis de plusieurs façons.]

Sont-ils des mixins définis dans un module d'enregistrement actif?

[Dans ce cas,

validates_presence_of est défini dans fournisseur/rails/activerecord/lib/active_record/validations.rb

belongs_to est défini dans fournisseur/rails/activerecord/lib/active_record/associations.rb

ActiveRecord est un grand système, comprend de nombreux modules, mixins, etc.

Remarque, pour voir où les méthodes sont définies, j'utilise http://www.gotapi.com/rubyrails pour chaque méthode, voir le lien "Afficher la source" au bas de la définition.

]

29

Le corps d'une définition de classe est un contexte d'exécution pour le code comme tout autre. Le code est exécuté dans le contexte de la classe (ce qui signifie que self est l'objet de la classe, qui est une instance de la classe). Vous pouvez avoir des locals et des variables d'instance (qui appartiendront à l'objet de classe lui-même plutôt qu'à des instances de la classe) et vous pouvez appeler n'importe quelle méthode à laquelle répond l'objet de classe. Le code est exécuté une fois le bloc de définition de classe terminé.

Dans ce cas, ActiveRecord :: Base définit les méthodes de classe validates_presence_of et belongs_to.

11

Ce sont des méthodes de classe ou des méthodes 'singleton'. Celui que vous devriez connaître est attr_accessor. Nous pouvons implémenter quelque chose comme ça dans une classe de test.

class Klass 
    def self.add_getter_and_setter(symbol) 
    module_eval "def #{symbol}; @#{symbol}; end" 
    module_eval "def #{symbol}=(val); @#{symbol} = val; end" 
    end 
end 

class Person < Klass 
    add_getter_and_setter :name 
    add_getter_and_setter :phone 
end 

person = Person.new 
person.name = 'John Smith' 
person.phone = '555-2344' 
person # returns <Person:0x28744 @name="John Smith", @phone="555-2344"> 

Dans l'exemple ci-dessus nous avons créé la méthode de classe avec « def self.add_getter_and_setter », mais ce n'est pas la seule façon.

class Klass 
    class << self # opens the singleton class 
    def add_getter_and_setter(symbol) # note we dont specify self as it is already within the context of the singleton class 
     .. 
    end 
    end 
end 

Utilisation de extend. Le module # extend est une méthode qui étend une classe avec des méthodes de classe de même que la méthode Module # include inclut une classe avec des méthodes d'instance.

class Klass 
    extend(Module.new do 
    def add_getter_and_setter(symbol) 
     .. 
    end 
    end) 
end 

Si Klass a déjà été défini, nous pouvons rouvrir pour ajouter des méthodes de classe

class Klass 
end 

def Klass.add_getter_and_setter(symbol) 
    .. 
end 

# or 

class << Klass 
    def add_getter_and_setter(symbol) 
    .. 
    end 
end 

Eh bien ce sont quelques façons que je sais comment faire si vous voyez une syntaxe différente réaliser à son tout faire la même chose. Remarque: dans les rails, une méthode de classe commune que nous utilisons tous est 'trouver'. Il est exécuté directement à partir de la classe Model.

person = Person.find(1) # finds a person with id:1 
Questions connexes