2009-11-24 2 views
0

J'utilise la gemme acts_as_taggable_on et je voudrais ajouter une méthode à l'un des fichiers source gem (tag.rb), mais je ne veux pas modifier la source gem en aucune façon.Comment ajouter une méthode à une gemme ruby ​​sans modifier la source gem?

J'ai essayé de créer mon propre fichier tag.rb dans le répertoire /app/models ou dans le répertoire /lib, puis en ajoutant la méthode souhaitée pour ce fichier attendant que Ruby va fusionner les deux fichiers tag.rb

Mais quand je fais, je reçois un NoMethodError: undefined method ...

Qu'est-ce qui me manque?

+0

Excuses pour ma réponse sans instruction, j'ai cliqué sur "supprimer" dessus, donc j'espère qu'il mourra d'une mort horrible. Je n'étais pas au courant de la possibilité de rouvrir des cours en Ruby, d'où ma réponse. – Makis

Répondre

3

Je pense que vous avez raison de rouvrir la classe Tag. Je ne voudrais pas introduire un autre niveau d'héritage à moins que cela ne soit vraiment logique pour votre code.

Je ne suis pas sûr, au-dessus de ma tête, pourquoi la réouverture de la classe Tag n'a pas fonctionné. Quelques réflexions:

1 - Lorsque vous avez écrit votre propre classe Tag, est-elle descendue d'ActiveRecord :: Base? La classe Tag dans les actes comme taggable sur le fait, et je pourrais voir comment négliger cela pourrait gâcher les choses.

2 - Si j'avais besoin d'un emplacement pour mettre du code qui rouvrait une classe plugin pour une seule méthode, je l'aurais probablement placé dans un fichier d'initialisation (tel que config/initializers/tag_patch.rb). Juste pour garder les choses propres.

3 - Si tout le reste échoue et que vous ne pouvez toujours pas rouvrir la classe Tag correctement (pour une raison quelconque) il existe d'autres techniques de métaprogrammation que vous pouvez essayer d'ajouter à la méthode. Par exemple:

Tag.send(:define_method, “method_name”) do 
    #code for your method 
end 
+0

Cela semble fonctionner. Je suppose que votre point # 2 était la magie. Obtenir le code dans les initialiseurs était probablement ce dont j'avais besoin (bien que je pensais pouvoir mettre mon tag.rb dans/lib aussi). – rswolff

+2

Qu'est-ce qui ne va pas avec class_eval, semble une façon plus claire et plus claire de rouvrir une classe. – nitecoder

+0

Je pense que railsninja est juste, Tag.class_eval est probablement la voie la plus claire à suivre. Cela ne m'est pas venu à l'esprit lorsque j'ai écrit l'exemple define_method. – PreciousBodilyFluids

2

Attendez, vous ne devriez pas ajouter la méthode au fichier , mais à la place classe. Connaissez-vous le concept de reopening the class? Vous ne pouvez pas ajouter une méthode en nommant simplement votre fichier comme celui dans lequel la classe d'origine est définie. Heureusement. :)

Questions connexes