J’ai fait quelques lectures sur l’extension de classe de ActiveRecord:Base si mes modèles aurait certaines méthodes spéciales. Quel est le moyen facile de l’étendre (tutoriel étape par étape) ?
Réponses
Trop de publicités?Il y a plusieurs approches :
À L'Aide De ActiveSupport::Inquiétude (De Préférence)
Lire la ActiveSupport::le Souci de la documentation pour plus de détails.
Créez un fichier appelé active_record_extension.rb
dans la lib
répertoire.
module ActiveRecordExtension
extend ActiveSupport::Concern
# add your instance methods here
def foo
"foo"
end
# add your static(class) methods here
module ClassMethods
def bar
"bar"
end
end
end
# include the extension
ActiveRecord::Base.send(:include, ActiveRecordExtension)
Créez un fichier dans l' config/initializers
- répertoire extensions.rb
et ajouter la ligne suivante dans le fichier:
require "active_record_extension"
L'héritage
Reportez-vous à Toby de réponse.
Monkey patching
Créez un fichier dans l' config/initializers
- répertoire active_record_monkey_patch.rb
.
class ActiveRecord::Base
#instance method, E.g: Order.new.foo
def foo
"foo"
end
#class method, E.g: Order.top_ten
def self.top_ten
limit(10)
end
end
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.
Certaines personnes, lorsqu'ils sont confrontés à un problème, penser "je sais, je vais utiliser monkey patching." Maintenant, ils ont deux problèmes.
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.
Vous pouvez également utiliser ActiveSupport::Concern
et plus des Rails de base idiomatiques comme:
module MyExtension
extend ActiveSupport::Concern
def foo
end
module ClassMethods
def bar
end
end
end
ActiveRecord::Base.send(:include, MyExtension)
[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éthodes en ClassMethods
inclus en tant que méthodes de la classe. E. g. sur un FooBar < ActiveRecord::Base
vous aurez: FooBar.bar
et FooBar#foo
http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
Avec 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.
Les 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:
Considérons 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:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
L'Article Modèle:
class Article < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#return the article with least number of comments
end
end
Modèle D'Événement
class Event < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#returns the event with least number of comments
end
end
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.
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable
end
# for the given article/event returns the first comment
def find_first_comment
comments.first(created_at DESC)
end
module ClassMethods
def least_commented
#returns the article/event which has the least number of comments
end
end
end
Et Maintenant, vos modèles ressembler à ceci :
Modèle Commentaire:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
L'Article Modèle:
class Article < ActiveRecord::Base
include Commentable
end
Modèle D'Événement
class Event < ActiveRecord::Base
include Commentable
end
Un point que je voudrais souligner tout en utilisant les Préoccupations, les Inquiétudes devraient être utilisés pour "domaine" groupement plutôt que de la "technique" de regroupement. Par exemple, un domaine de regroupement est comme "Commentable', 'Tagable", etc. Une technique basée sur le groupement sera comme "FinderMethods', 'ValidationMethods'.
Voici un lien vers un post que j'ai trouvé très utile pour la compréhension des préoccupations dans les Modèles: [https://github.com/justin808/fat-code-refactoring-techniques/pull/9][1]
Espérons que le writeup aide :)