简体   繁体   English

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

[英]How to write a Rails mixin that spans across model, controller, and view

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

The model stuff is fairly easy, I just have to include the module at the beginning, eg: 模型的东西相当简单,我只需要在开头包含模块,例如:

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

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? 基本上我打算只为控制器和视图做一个包含Sendable :: Controller和Sendable :: View(或等效的),但有没有更简洁的方法呢? I 'm after a neat way to have a bunch of common code between my model, controller, and view. 我正在以一种巧妙的方式在我的模型,控制器和视图之间拥有一堆通用代码。

Edit: Just to clarify, this just has to be shared across 2 or 3 models. 编辑:只是为了澄清,这只需要在2或3个模型中共享。

You could pluginize it (use script/generate plugin). 你可以插件(使用脚本/生成插件)。

Then in your init.rb just do something like: 然后在init.rb中执行以下操作:

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

And along with your self.included that should work just fine. 并伴随着你的自我。包括应该工作得很好。

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

If that code needs to get added to all models and all controllers, you could always do the following: 如果需要将该代码添加到所有模型和所有控制器,则可以始终执行以下操作:

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

# application.rb
class ApplicationController
  include Iso
end

If you needed functions from this module available to the views, you could expose them individually with helper_method declarations in application.rb. 如果您需要视图可用的此模块中的函数,则可以使用helper_method声明单独公开它们。

如果你去插件路线,请查看Rails-Engines ,它们旨在以清晰的方式将插件语义扩展到控制器和视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rails-在视图,控制器和模型中使用一组功能 - Rails- Using a set of functions across the view , controller and model 如何在Rails中基于范围的多租户应用程序中创建可跨公司的代理模型 - How do I create an Agent model that can spans across Companies in a scope based multi tenancy app in Rails 如何将模块混合到Rails 3控制器中 - How do you mixin a module into a Rails 3 controller Rails:如何跨视图访问模型和控制器数据? - Rails: How do you access model and controller data across views? Rails-视图或控制器中的查询模型? - Rails - query model in view or controller? 使用控制器构建视图,但在Rails中没有模型 - Building a view with a controller but no model in rails 如何编写/运行模型/视图/控制器以外的文件的规格 - how to write/run specs for files other than model/view/controller 跨父应用程序和引擎的模型关联 - Model association that spans across parent app and engine Rails 4如何为用户(控制器,视图,模型)注册课程 - Rails 4 how to make enrolment to a course for users (controller, view, model) 如何通过控制器从Rails视图调用模型方法? - How to call a model method from rails view through a controller?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM