2009-06-15 7 views
1

je ceci:Initialiser un module mixte pour un modèle

class Bullet < ActiveRecord::Base 
    include StagedVersionMethods 
    ... 
end 

Et ce

module StagedVersionMethods  
    def initialize 
    puts self.bullet_id 
    end 
end 

Lorsque je crée une instance de Bullet, les modules initialize feux de méthode, mais je reçois un ActiveRecord erreur: ... activerecord-2.2.2/lib/enregistrement_actif/attribute_methods.rb: 268: dans `read_attribute '

Mon intention est d'initialiser une variable d'instance pour laquelle j'ai besoin de la prima ry valeur clé de l'enregistrement que je mélange dans. D'autres méthodes dans le module fonctionneront alors avec cette variable d'instance.

Le module included() callback ne correspond pas non plus à la tâche, car self, dans ce contexte, est le module et non l'enregistrement AR.

Comment cela devrait-il être abordé?

Merci

Répondre

0

Si vous définissez comme initialize:

def initialize(*atts) 
    super(*atts) 
    puts self.bullet_id 
end 

alors je pense qu'il fera ce que vous voulez qu'il va mettre en place l'objet correctement pour vous en utilisant l'initialisation ActiveRecord premier. Cependant, je ne suis pas certain de la solidité de cette approche pour ce que vous essayez d'accomplir. Il peut être plus approprié de créer cette variable d'instance lors de l'accès plutôt que lorsque l'objet est initialisé.

Il est difficile de dire ce que vous voulez faire de la variable d'instance.

+0

Merci Shadwell, La variable d'instance sera une copie de l'instance « soi », mais avec des modifications ont été apportées. Il représente une copie temporaire de la puce "parent", et le module va mélanger des méthodes au MOdel - des méthodes comme has_temp_version ?, apply_temp_version, discard_temp_version et autres. J'ai essayé l'approche que vous avez suggérée (ce qui est parfaitement logique) mais les attributs de self, y compris bullet_id, sont tous nuls. J'utilise votre deuxième suggestion actuellement et cela fonctionne bien - juste un peu plus de plomberie que j'aurais aimé. Salutations – Paul

4

Surcharge de l'initialiseur sur ActiveRecord peut avoir des effets secondaires étranges qui s'avèrent difficiles à déboguer, donc ce n'est pas recommandé. L'approche recommandée consiste à utiliser le rappel after_initialize fourni par ActiveRecord. Vous pouvez toujours mélanger ce comportement via un module ...

module MyCleverMixin 

    def after_initialize 
    puts "I'm Initializing!" 
    end 

end 


class MyModel < ActiveRecord 

    include MyCleverMixin 

end 
+0

Merci. Le fait est que je m'attendais à ce que klass soit mon modèle dans lequel je mélange le module, mais la classe de klass est "Class" et le bloc ne sera jamais appelé. Est-ce que je prends la mauvaise extrémité du bâton? Merci beaucoup. – Paul

+0

En fait, nous pouvons simplifier cela en définissant simplement after_initialize dans notre mixin. S'il vous plaît jeter un oeil à mon code édité ci-dessus pour un exemple de travail – user123226

+0

Devrait-il être 'include MyCleverMixin'? Une autre chose à noter est que le rappel after_initialize n'est pas appelé lorsque vous avez trouvé des puces existantes dans la base de données. Vous devez également définir after_find. – Shadwell

Questions connexes