Question

Dans le but de réduire la duplication de code dans ma petite application Rails, je travaille à obtenir du code commun entre mes modèles dans son propre module séparé, jusqu'à présent, tout va bien.

Le modèle est assez simple, il suffit d'inclure le module au début, par exemple:

class Iso < Sale
  include Shared::TracksSerialNumberExtension
  include Shared::OrderLines
  extend  Shared::Filtered
  include Sendable::Model

  validates_presence_of   :customer
  validates_associated    :lines

  owned_by :customer

  def initialize( params = nil )
    super
    self.created_at ||= Time.now.to_date
  end

  def after_initialize
  end

  order_lines             :despatched

  # tracks_serial_numbers   :items
  sendable :customer

  def created_at=( date )
    write_attribute( :created_at, Chronic.parse( date ) )
  end
end

Cela fonctionne bien, mais je vais maintenant avoir un contrôleur et un code d'affichage communs à ces modèles, jusqu'à présent, j'ai ceci pour mes éléments à envoyer:

# This is a module that is used for pages/forms that are can be "sent"
# either via fax, email, or printed.
module Sendable
  module Model
    def self.included( klass )
      klass.extend ClassMethods
    end

    module ClassMethods
      def sendable( class_to_send_to )
        attr_accessor :fax_number,
                      :email_address,
                      :to_be_faxed,
                      :to_be_emailed,
                      :to_be_printed

        @_class_sending_to ||= class_to_send_to

        include InstanceMethods
      end

      def class_sending_to
        @_class_sending_to
      end
    end # ClassMethods

    module InstanceMethods
      def after_initialize( )
        super
        self.to_be_faxed    = false
        self.to_be_emailed  = false
        self.to_be_printed  = false

        target_class = self.send( self.class.class_sending_to )
        if !target_class.nil?
          self.fax_number     = target_class.send( :fax_number )
          self.email_address  = target_class.send( :email_address )
        end
      end
    end
  end # Module Model
end # Module Sendable

En gros, je prévois de faire simplement include avec Sendable :: Controller, et Sendable :: View (ou l’équivalent) pour le contrôleur et la vue, mais existe-t-il une méthode plus propre pour le faire? Je cherche un moyen génial d’avoir un tas de codes communs entre mon modèle, mon contrôleur et ma vue.

Éditer: Juste pour clarifier, cela doit juste être partagé entre 2 ou 3 modèles.

Était-ce utile?

La solution

Vous pouvez le brancher (utilisez le plugin script / generate).

Ensuite, dans votre init.rb, faites quelque chose comme:

ActiveRecord::Base.send(:include, PluginName::Sendable)
ActionController::Base.send(:include, PluginName::SendableController)

Et avec votre auto.included cela devrait fonctionner très bien.

Découvrez quelques-uns des plugins act_ *, il s'agit d'un modèle assez courant ( http://github.com/technoweenie/acts_as_paranoid/tree/master/init.rb , vérifiez la ligne 30)

Autres conseils

Si ce code doit être ajouté à tous les modèles et à tous les contrôleurs, vous pouvez toujours effectuer les opérations suivantes:

# maybe put this in environment.rb or in your module declaration
class ActiveRecord::Base
  include Iso
end

# application.rb
class ApplicationController
  include Iso
end

Si vous aviez besoin des fonctions de ce module disponibles pour les vues, vous pouvez les exposer individuellement avec des déclarations helper_method dans application.rb.

Si vous suivez la route du plugin, consultez Rails-Engines , qui sont destinés à être étendus. sémantique du plug-in aux contrôleurs et aux vues de manière claire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top