J'ai fait quelques lectures sur la façon d'étendre ActiveRecord: Classe de base afin que mes modèles aient des méthodes spéciales. Quelle est la manière simple de l'étendre (tutoriel étape par étape)?
ruby-on-rails
extend
rails-activerecord
xpepermint
la source
la source
Réponses:
Il existe plusieurs approches:
Utilisation d'ActiveSupport :: Concern (préféré)
Lisez la documentation ActiveSupport :: Concern pour plus de détails.
Créez un fichier appelé
active_record_extension.rb
dans lelib
répertoire.Créez un fichier dans le
config/initializers
répertoire appeléextensions.rb
et ajoutez la ligne suivante au fichier:Héritage (préféré)
Reportez-vous à la réponse de Toby .
Patching de singe (doit être évité)
Créez un fichier dans le
config/initializers
répertoire appeléactive_record_monkey_patch.rb
.La célèbre citation sur les expressions régulières de Jamie Zawinski peut être réutilisée pour illustrer les problèmes associés à la correction des singes.
La correction des singes est simple et rapide. Mais, le temps et les efforts économisés sont toujours récupérés dans le futur; avec intérêt composé. Ces jours-ci, je limite monkey patching pour prototyper rapidement une solution dans la console des rails.
la source
require
accéder au fichier à la fin deenvironment.rb
. J'ai ajouté cette étape supplémentaire à ma réponse.ImprovedActiveRecord
et en hériter, lorsque vous utilisezmodule
, vous mettez à jour la définition de la classe en question. J'utilisais l'héritage (à cause d'années d'expérience Java / C ++). Ces jours-ci, j'utilise principalement des modules.Refinements
qui résout la plupart des problèmes liés au patching des singes ( yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice ). Parfois, une fonctionnalité est là juste pour vous contraindre à tenter le destin. Et parfois vous le faites.Vous pouvez simplement étendre la classe et utiliser simplement l'héritage.
la source
abstract_models
. Où dois-je le mettre?self.abstract_class = true
à votreAbstractModel
. Rails reconnaîtra désormais le modèle comme un modèle abstrait.AbstractModel
dans la base de données. Qui savait qu'un simple passeur m'aiderait à SÉCHER les choses! (Je commençais à grincer des dents ... c'était mauvais). Merci Toby et Harish!Vous pouvez également utiliser
ActiveSupport::Concern
et être plus idiomatique de base de Rails comme:[Modifier] suite au commentaire de @daniel
Ensuite, tous vos modèles auront la méthode
foo
incluse comme méthode d'instance et les méthodesClassMethods
incluses comme méthodes de classe. Par exemple sur unFooBar < ActiveRecord::Base
vous aurez:FooBar.bar
etFooBar#foo
http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
la source
InstanceMethods
c'est obsolète depuis Rails 3.2, mettez simplement vos méthodes dans le corps du module.ActiveRecord::Base.send(:include, MyExtension)
un initialiseur, puis cela a fonctionné pour moi. Rails 4.1.9Avec Rails 4, le concept d'utilisation des préoccupations pour modulariser et sécher vos modèles a été mis en évidence.
Les préoccupations vous permettent essentiellement de regrouper le code similaire d'un modèle ou sur plusieurs modèles dans un seul module, puis d'utiliser ce module dans les modèles. Voici un exemple:
Considérez un modèle d'article, un modèle d'événement et un modèle de commentaire. Un article ou un événement a de nombreux commentaires. Un commentaire appartient à un article ou à un événement.
Traditionnellement, les modèles peuvent ressembler à ceci:
Modèle de commentaire:
Modèle d'article:
Modèle d'événement
Comme nous pouvons le constater, il existe un élément de code important commun à la fois au modèle d'événement et d'article. En utilisant les préoccupations, nous pouvons extraire ce code commun dans un module distinct Commentable.
Pour cela, créez un fichier commentable.rb dans app / model / concern.
Et maintenant, vos modèles ressemblent à ceci:
Modèle de commentaire:
Modèle d'article:
Modèle d'événement
Un point que j'aimerais souligner lors de l'utilisation des préoccupations est que les préoccupations devraient être utilisées pour un groupement «basé sur un domaine» plutôt qu'un groupement «technique». Par exemple, un groupement de domaine est comme «Commentable», «Taggable» etc. Un groupement technique sera comme «FinderMethods», «ValidationMethods».
Voici un lien vers un article que j'ai trouvé très utile pour comprendre les préoccupations dans les modèles.
J'espère que la rédaction aidera :)
la source
Étape 1
Étape 2
Étape 3
la source
Les rails 5 fournissent un mécanisme intégré d'extension
ActiveRecord::Base
.Ceci est réalisé en fournissant une couche supplémentaire:
et tous les modèles héritent de celui-là:
Voir par exemple cet article de blog .
la source
Juste pour ajouter à ce sujet, j'ai passé un certain temps à essayer de tester de telles extensions (j'ai suivi la
ActiveSupport::Concern
voie.)Voici comment j'ai mis en place un modèle pour tester mes extensions.
la source
Avec Rails 5, tous les modèles sont hérités d'ApplicationRecord et cela donne un bon moyen d'inclure ou d'étendre d'autres bibliothèques d'extensions.
Supposons que le module de méthodes spéciales doit être disponible sur tous les modèles, incluez-le dans le fichier application_record.rb. Si nous voulons l'appliquer à un ensemble particulier de modèles, incluez-le dans les classes de modèles respectives.
Si vous souhaitez que les méthodes définies dans le module soient des méthodes de classe, étendez le module à ApplicationRecord.
J'espère que cela aidera les autres!
la source
j'ai
dans un initialiseur
Pour un module comme ci-dessous
la source