Comment créer et utiliser un module en utilisant Ruby on Rails 3?

90

J'utilise Ruby on Rails 3 et je souhaite déplacer du code personnalisé et partagé dans un module.

  1. Quelle syntaxe dois-je utiliser pour écrire le code du module?
  2. Dans quel dossier de mon application dois-je placer le fichier du module?
  3. Comment dois-je inclure ce module dans une ou plusieurs classes d'automates?
  4. Quelle autre action, le cas échéant, dois-je utiliser pour utiliser le module personnalisé n'importe où dans mon application?
  5. Comment appeler des méthodes dans le module depuis mon application?

Merci d'avance.

user502052
la source
2
Très bien! J'en avais besoin.
Arup Rakshit

Réponses:

115

À 1. Un module est créé / ouvert en disant simplement:

module MyModule
  def first_module_method
  end
end

Vers 2. Le libdossier. Si vous souhaitez organiser vos modules dans le libdossier, vous pouvez les placer eux-mêmes dans des modules. Par exemple, si vous vouliez un sous-dossier, super_modulesvos modules seraient définis comme suit:

module SuperModules
  module MyModule
    def first_module_method
    end
  end
end

Vers 3./5. Lorsque vous incluez le module dans une classe, vous pouvez simplement appeler les méthodes des modules comme si elles étaient définies dans la classe:

class MyClass
  include MyModule
  def some_method
    first_module_method #calls module method
  end
end

Pour 4. Tout d'abord, assurez-vous que votre module est vraiment nécessaire dans chaque classe de votre application. Si ce n'est pas le cas, il est logique de ne l'inclure que là où c'est nécessaire pour ne pas gonfler les classes qui n'en ont pas besoin de toute façon. Si vous voulez vraiment le module partout, incluez la hiérarchie des classes de vos classes dans l'application. Voulez-vous le module dans tous les modèles? Vous pouvez ouvrir ActiveRecord :: Base et y ajouter votre module.

Stephan
la source
2
Pour organiser les fichiers, puis-je créer un sous-dossier dans le dossier «lib»? Si oui, qu'est-ce qui change?
user502052
2
@ user502052 J'ai mis à jour la réponse au point 2 pour répondre à cette question.
Stephan
3
Beaucoup de choses ne sont pas claires ici. Quels noms de fichiers donner? Comment appeler les méthodes sans inclure tout le module? Je ne peux pas croire qu'il y ait autant de votes positifs car je ne sais toujours pas comment utiliser un module à la fin.
Augustin Riedinger
5
Une fois que vous avez créé un module comme ci-dessus en l'incluant dans le libdossier, une remarque importante est d'activer Rails3 pour décommenter la ligne config\application.rbpour config.autoload_paths- lisez par exemple stackoverflow.com/questions/1073076/rails-lib-modules-and ... Remarque également que vous devez faire attention à utiliser un nom de fichier pour votre module qui correspond au nom du module lui-même. Donc, si vous l'enregistrez lib/test/my_module.rb, vous devez include Test::MyModule- pour plus de détails, voir stackoverflow.com/questions/4073856/rails-3-autoload
sameers
6
Je viens de trouver ma vieille réponse. :( Je veux voter contre. Ne mettez rien dans la lib! Mettez votre code (y compris les modules supplémentaires) app/modelssi le code a besoin d'accéder à d'autres modèles. Si votre code est vraiment une 'bibliothèque' et peut exister seul, je suggérer de vendre une gemme. Pour des exemples, voir github.com/shageman/the_next_big_thing
Stephan
3

A> 1. Vous pouvez utiliser la même syntaxe que toute autre classe ruby. Par exemple, je définis un module VehicleClassifer qui va utiliser la méthode classify_vehicle pour classer un véhicule en fonction du nombre de roues qu'il reçoit en entrée.

module VehicleClassifer
  def classify_vehicle(number_of_wheels)
    VehicleType.where("number_of_wheels = ?", number_of_wheels)
  end
end

A> 2. Les modules sont généralement stockés dans le dossier / lib.

les questions 3, 4, 5 ont plus ou moins la même réponse. vous pouvez utiliser

class SomeController < ApplicationController
  include VehicleClassfier

  def index 
    classify_vehicle(4)  
  end
end

dans la classe que vous utilisez le module et vous aurez accès à toutes les méthodes du module.

De plus, si vous avez besoin d'utiliser un module dans votre application, vous pouvez l'inclure dans votre contrôleur d'application.

Shreyas
la source
2
J'ai essayé cela et j'ai eu une erreur de méthode non définie. Une idée de ce que je fais mal?
Tony
Êtes-vous sûr que votre module est accessible? stackoverflow.com/questions/6604272/… peut-être vous aide?
Shreyas
1
@Tony - Vous devrez peut-être redémarrer votre serveur - même en mode dev, pour que les méthodes du module soient disponibles. Et chaque fois que vous modifiez le code de votre module, vous devez redémarrer le serveur. Par exemple, si une erreur ou une erreur sur l'ancien code, mais mettez en évidence le nouveau code sur cette ligne dans le msg d'erreur - très déroutant.
JosephK
Une idée comment inclure et utiliser ces modules personnalisés à l'intérieur ApplicationHelper?
WM