当前位置:  开发笔记 > 后端 > 正文

如何编写跨越模型,控制器和视图的Rails mixin

如何解决《如何编写跨越模型,控制器和视图的Railsmixin》经验,为你挑选了2个好方法。

为了减少我的小Rails应用程序中的代码重复,我一直在努力将我的模型之间的公共代码添加到它自己的独立模块中,到目前为止一直很好.

模型的东西相当简单,我只需要在开头包含模块,例如:

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

这工作正常,但是,现在,我将要有一些控制器和视图代码,这些代码在这些模型之间也是常见的,到目前为止,我有这个用于我的可发送内容:

# 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

基本上我打算只为控制器和视图做一个包含Sendable :: Controller和Sendable :: View(或等效的),但有没有更简洁的方法呢?我正在以一种巧妙的方式在我的模型,控制器和视图之间拥有一堆通用代码.

编辑:只是为了澄清,这只需要在2或3个模型中共享.



1> nikz..:

你可以插件(使用脚本/生成插件).

然后在init.rb中执行以下操作:

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

并伴随着你的自我.包括应该工作得很好.

查看一些acts_*插件,这是一个非常常见的模式(http://github.com/technoweenie/acts_as_paranoid/tree/master/init.rb,检查第30行)



2> hoyhoy..:

如果需要将该代码添加到所有模型和所有控制器,则可以始终执行以下操作:

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

# application.rb
class ApplicationController
  include Iso
end

如果您需要视图可用的此模块中的函数,则可以使用helper_methodapplication.rb中的声明单独公开它们.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有