2011-11-22 48 views
2

我正在編寫一個應用程序,其中許多(但不是全部)ActiveRecord模型具有hash列。這是使用隨機MD5散列創建時填充的,用於引用單個對象而不是其ID。要做到這一點,我已經包括在相應的模型下面的模塊,並在所有的控制器,而不是find使用find_by_id_or_hash!()Rails 3:在模塊中使用'before_create'(適用於ActiveRecord模型)

module IdOrHashFindable 

    def self.included(base) 
    base.extend(ClassMethods) 
    end 

    module ClassMethods 

    before_create :create_hash    ## <-- THIS FAILS 

    # legacy. in use only until find by ID is phased out altogether 
    def find_by_id_or_hash!(id_or_hash) 
     id_or_hash.to_s.size >= 32 ? find_by_hash!(id_or_hash) : find(id_or_hash) 
    end 
    end 

    def to_param; self.hash end 
    def create_hash; self.hash = Support.create_hash end 

end 

爲了讓事情幹,我想有before_create調用也模塊內。不過,我不斷收到任何

undefined method `before_create' for IdOrHashFindable:Module 

undefined method `before_create' for IdOrHashFindable::ClassMethods:Module 

根據我放哪兒了。這是有道理的(畢竟,我正在調用一個函數,而不是定義它),但我仍然想知道如何做到這一點。 (我不能覆蓋before_create,因爲還有其他before_create調用)。

另外,對於包含此模塊的所有型號,都應用相當類似的測試。我如何持續測試此功能?我是否將自定義的describe ... end塊和require寫入每個model_spec.rb的適用範圍?如何在不訴諸全局變量的情況下傳遞正確的模型?

任何想法,將不勝感激!

回答

6

您必須將類方法invokation在class_eval,或直接調用它想:

module IdOrHashFindable 

    def self.included(base) 
    base.extend(ClassMethods) 
    base.before_create :create_hash 
    # or 
    base.class_eval do 
     before_create :create_hash 
    end 
    end 

end 

,因爲當你把方法的模塊,它會directy調用它作爲模塊的方法

+3

我d建議使用[ActiveSupport關注](http://opensoul.org/blog/archives/2011/02/07/concerning-activesupportconcern/) – tjwallace

+0

感謝有關Concern的信息。不知道。 – cvshepherd

相關問題