2008-09-16 56 views
5

爲了減少我的小Rails應用程序中的代碼重複,我一直致力於將我的模型之間的通用代碼轉換爲它自己的獨立模塊,所以非常好。如何編寫跨越模型,控制器和視圖的Rails mixin

模型的東西是相當容易的,我只需要在開頭包括模塊,如:

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 

基本上我打算只做一個包括可發送::控制器,以及可發送::視圖(或相當於)控制器和視圖,但是,有沒有更清晰的方法可以做到 這個?我在一個簡單的方法之後,在模型,控制器和視圖之間有一堆通用代碼。

編輯:只是爲了澄清,這隻需要共享2或3個模型。

回答

7

你可以插件(使用腳本/生成插件)。

然後在你的init.rb只是這樣做:

​​

並與您的self.included應該工作就好了一起。

檢查出一些acts_的*插件,這是一個很常見的模式(http://github.com/technoweenie/acts_as_paranoid/tree/master/init.rb,檢查第30行)

+0

我選擇了這個答案,儘管Hoyhoy's也很好,只是因爲它適合我做得更好一些。 – Mike 2008-09-17 23:12:46

+0

這真的是一回事。這是一個更好的語法。 – hoyhoy 2008-09-20 20:24:33

6

如果需要,添加到所有模型和所有的控制器代碼,你總是可以做到以下幾點:

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

# application.rb 
class ApplicationController 
    include Iso 
end 

如果您需要的功能,從這個模塊提供給意見,你可以公開他們的個人用在application.rb中聲明helper_method

+0

這就是我可能最終做的事情,只要我的函數等沒有任何名稱衝突,它應該不是問題? – Mike 2008-09-16 03:16:31

1

如果你去插件路線,做檢查出Rails-Engines,其意在插件的語義擴展到控制器和視圖以一種清晰的方式。

相關問題