2010-02-28 58 views
13

我有幾個方法想在模型之間共享,而不是複製和粘貼它們。在一個控制器中,我可以通過將方法放入application_controller.rb中來實現這一點,該方法會自動包含在每個控制器中。 模型有沒有類似的東西?如何跨模型共享代碼? (Rails 2.3)

謝謝!

回答

16

之間共享您可以創建一個名爲functionality.rblib目錄中的Rails應用程序的類似的東西。當模塊啓動時,以該模塊命名的文件自動加載它。例如,如果我想添加標記,以多種模式,我想創建一個名爲lib/flagging.rb,它應該是這樣的:

module Flagging 
    # Flags an object for further review 
    def flag! 
    self.update_attribute(:flagged, true) 
    end 

    # Clears all flags on an object 
    def deflag! 
    self.update_attribute(:flagged, false) 
    end 
end 

在每一個模式,我想這個功能添加到,我會做到以下幾點:

class Foo < ActiveRecord::Base 
    include Flagging 
end 

我然後就可以這樣做:

foo = Foo.create 
foo.flag! 
+0

謝謝!這就是我最終使用 – 2010-03-01 00:10:26

+1

的傢伙。這都是關於lib目錄的。我已經開始在那裏添加更多的代碼,它只是組織事物的便利之處。 – 2010-03-01 06:12:52

3

您可以a)做一些類似application_controller創造從別人可以繼承或b)使用一個模塊的模型類。

2

有許多方法可以在2個模型類之間共享方法。

  • 如果模型彼此相關,例如使用模型,則使用inheritance。一個包含方法的共享父類,或者一個包含方法的另一個子類。
  • 使用modules/mixins可以多個模型
+0

'將這些方法轉換爲兩種模型都可以訪問的輔助方法 - 我認爲模型無法訪問輔助方法。這怎麼可能(看起來像我試圖做的最乾淨的方法) – 2010-02-28 23:30:45

+0

你說得對。我正在考慮效用方法,而不是鐵路方面的「輔助方法」。所以mixin方法比實用方法更有用。 – marklai 2010-03-01 00:16:19

0

要添加到Josh的答案中,有時您可能想共享一些定義多態關聯的代碼。你不能只是把has_many方法調用的模塊中,因爲你會得到一個錯誤,例如所謂的可投票模塊:

undefined method `has_many' for Voteable:Module (NoMethodError) 

因此,相反,你需要使用self.included(base)方法和base.instance_eval。這裏有一個例子我Voteable模塊:

module Voteable 

    def self.included(base) 
    base.instance_eval do 
     has_many :votes, as: :voteable 
     has_many :voters, through: :votes 
    end 
    end 

    def voted_up_by?(user) 
    user and votes.exists?(value: 1, voter_id: user) 
    end 

    def voted_down_by?(user) 
    user and votes.exists?(value: -1, voter_id: user) 
    end 

end 

現在你可以在include Voteable車型,將有這種行爲。這將執行self.included(base)方法,它將定義包含類的關聯。

+0

在Rails 3中,這更容易 - 您可以替換'def self.included(base)base。instance_eval'帶有'擴展ActiveSupport :: Concern included'。 – 2013-10-17 23:42:39