161 votes

Rails extension ActiveRecord::Base

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) ?

339voto

Harish Shetty Points 38877

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.

70voto

Toby Hede Points 22128

Vous pouvez simplement étendre la classe et utiliser simplement l’héritage.

21voto

nikola Points 1190

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

21voto

Aaditi Jain Points 166

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 :)

8voto

Vitaly Kushner Points 3975

Étape 1

Étape 2

Étape 3

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X