如何编写跨模型,控制器和视图的Rails混合 [英] How to write a Rails mixin that spans across model, controller, and view

查看:69
本文介绍了如何编写跨模型,控制器和视图的Rails混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了减少我的小Rails应用程序中的代码重复,到目前为止,我一直在努力将模型之间的通用代码放入其自己的单独模块中。

In an effort to reduce code duplication in my little Rails app, I've been working on getting common code between my models into it's own separate module, so far so good.

模型的工作相当简单,我只需要在开始时包含模块,例如:

The model stuff is fairly easy, I just have to include the module at the beginning, e.g.:

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 working fine, now however, I'm going to have some controller and view code that's going to be common between these models as well, so far I have this for my sendable stuff:

# 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(或等效视图),但是,有没有更清洁的方法呢?我正在用一种巧妙的方法在我的模型,控制器和视图之间使用一堆通用代码。

Basically I'm planning on just doing an include Sendable::Controller, and Sendable::View (or the equivalent) for the controller and the view, but, is there a cleaner way to do this? I 'm after a neat way to have a bunch of common code between my model, controller, and view.

编辑:澄清一下,这只是必须共享跨2或3个模型。

Just to clarify, this just has to be shared across 2 or 3 models.

推荐答案

您可以对其进行插件(使用脚本/生成插件)。

You could pluginize it (use script/generate plugin).

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

Then in your init.rb just do something like:

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

以及您的self.include都应该很好用。

And along with your self.included that should work just fine.

检查一些acts_ *插件,这是一个非常常见的模式(< a href = http://github.com/technoweenie/acts_as_paranoid/tree/master/init.rb rel = nofollow noreferrer> http://github.com/technoweenie/acts_as_paranoid/tree/master/init.rb ,检查第30行)

Check out some of the acts_* plugins, it's a pretty common pattern (http://github.com/technoweenie/acts_as_paranoid/tree/master/init.rb, check line 30)

这篇关于如何编写跨模型,控制器和视图的Rails混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆