Les Rails s'étendant ActiveRecord::Base
J'ai fait un peu de lecture sur la façon de prolonger ActiveRecord:la classe de Base donc, mes modèles ont des méthodes un peu spéciales. Quel est le moyen le plus facile de l'étendre (étape par étape tutoriel)?
- Ce type d'extensions? Nous avons vraiment besoin de plus pour aller sur.
Vous devez vous connecter pour publier un commentaire.
Il y a plusieurs approches :
À L'Aide De ActiveSupport::Inquiétude (De Préférence)
Lire la ActiveSupport::Inquiétude documentation pour plus de détails.
Créer un fichier appelé
active_record_extension.rb
dans lelib
répertoire.Créer un fichier dans le
config/initializers
répertoire appeléextensions.rb
et ajouter la ligne suivante dans le fichier:Héritage (De Préférence)
Reportez-vous à Toby réponse.
Monkey patching (Doit être évitée)
Créer 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 par Jamie Zawinski peuvent être réutilisées pour illustrer les problèmes associés avec le singe de correction.
Monkey patching est facile et rapide. Mais, le temps et l'effort économisé est toujours extraite de retour
dans le futur; avec l'intérêt composé. Ces jours-ci je limite le monkey patching rapidement un prototype d'une solution dans la console rails.
class MyActiveRecordExtensions
au lieu demodule MyActiveRecordExtensions
.require
le fichier à la fin deenvironment.rb
. J'ai ajouté cette étape supplémentaire à ma réponse.ImprovedActiveRecord
et hériter de cela, lorsque vous êtes à l'aide demodule
, vous êtes à la mise à jour de la définition de la classe en question. J'ai l'habitude d'utiliser l'héritage(cause des années de Java/C++ de l'expérience). Ces jours-ci j'ai surtout utiliser les modules.Refinements
qui aborde la plupart des problèmes avec monkey patching(yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice). Parfois, une fonctionnalité est là juste pour vous contraindre à tenter le sort. Et parfois, vous n'.ActiveSupport::Concern
, puis de le mélanger à une classe. C'est peut-être possible de l'utiliser ici?list
méthode, il obtient 10 lignes à partir de la base de données dans le module, puis je n'ai pas besoin de le copier dans chaque sous-classe.top_ten
. Vous pouvez la chaîne de cette méthode avec d'autres AR méthodes par exemple:Order.where('qty > ?', 10).top_ten
serializable_hash
vous devez utiliser leexclude
paramètre de la fonction. Si vous essayez de cibler qu'une classe alors il peut être préférable de remplacer la méthode dans cette classe. Voici un exemple: robots.thoughtbot.com/better-serialization-less-as-jsonclass_methods do
au lieu demodule ClassMethods
droit?require 'active_support/concern'
à lalib/active_record_extension.rb
fichier. Voir ActiveSupport Souci de documentationVous pouvez simplement étendre la classe et tout simplement utiliser l'héritage.
abstract_models
. Où dois-je le mettre?self.abstract_class = true
à votreAbstractModel
. Les Rails maintenant reconnaître le modèle comme un modèle abstrait.AbstractModel
dans la base de données. Qui aurait pensé qu'un simple poseur de m'aiderait à SEC les choses! (Je commence à grincer des dents...c'était mauvais). Merci Toby et Harish!Vous pouvez également utiliser
ActiveSupport::Concern
et plus les Rails de base idiomatiques comme:[Edit] après le commentaire de @daniel
Alors tous vos modèles auront la méthode
foo
inclus comme une méthode d'instance et les méthodesClassMethods
compris que les méthodes de la classe. E. g. sur unFooBar < ActiveRecord::Base
, vous aurez:FooBar.bar
etFooBar#foo
http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
InstanceMethods
est obsolète depuis des Rails 3.2, il suffit de mettre vos méthodes dans le module d'administration.ActiveRecord::Base.send(:include, MyExtension)
dans un initialiseur et puis cela a fonctionné pour moi. Rails 4.1.9Avec Rails 4, le concept de l'utilisation de préoccupations pour modulariser et SÉCHER vos modèles a été dans les hautes lumières.
Préoccupations fondamentalement, vous permettent de groupe similaire de code d'un modèle ou plusieurs modèles dans un seul module, puis utiliser ce module dans les modèles. Voici un exemple:
Envisager un modèle Article, un modèle d'Événement et un Commentaire de Modèle. Un article ou Un événement a de nombreux commentaires. Un commentaire appartient soit de l'article ou de l'événement.
Traditionnellement, les modèles peuvent ressembler à ceci:
Modèle Commentaire:
L'Article Modèle:
Modèle D'Événement
Comme on peut le remarquer, il existe un important morceau de code commun aux deux Cas et Modèle de l'Article. À l'aide des préoccupations que nous pouvons extraire de cette commune code dans un module séparé Commentable.
Pour cela créer un commentable.rb fichier app/model/préoccupations.
Et Maintenant vos modèles ressembler à ceci :
Modèle Commentaire:
L'Article Modèle:
Modèle D'Événement
Un point que je tiens à mettre en évidence lors de l'utilisation des Préoccupations est que Préoccupations devraient être utilisés pour "domaine" groupement plutôt que de "technique", le groupement des. Par exemple, un domaine de regroupement est comme "Commentable', 'Tagable", etc. Une technique basée sur le groupement sera comme "FinderMethods', 'ValidationMethods'.
Ici est un lien vers un post que j'ai trouvé très utile pour la compréhension des préoccupations dans les Modèles.
Espère que le writeup aide 🙂
Étape 1
Étape 2
Étape 3
Juste pour ajouter à ce sujet, j'ai passé un certain temps de travailler sur la façon de tester de telles extensions (je suis descendu de la
ActiveSupport::Concern
route.)Voici comment j'ai configuré un modèle pour mes extensions.
Rails de 5 fournit un mécanisme intégré pour l'extension de
ActiveRecord::Base
.Ceci est réalisé en fournissant couche supplémentaire:
et tous les modèles héritent de celle-là:
Voir, par exemple,ce billet de blog.
Avec des Rails 5, tous les modèles sont héritées de ApplicationRecord & il donne une belle façon d'inclure ou d'étendre à d'autres bibliothèques d'extension.
Supposons que les méthodes spéciales module doit être disponible sur tous les modèles, de l'inclure dans application_record.rb fichier. Si l'on veut appliquer ce pour un ensemble particulier de modèles, puis l'inclure dans le modèle des classes.
Si vous voulez avoir les méthodes définies dans le module sur les méthodes de la classe, d'étendre le module de ApplicationRecord.
Espère que ça aidera d'autres!!!
J'ai
dans un initialiseur
Pour un module comme ci-dessous