2013-01-21 28 views
9

我工作在一個小的DataMapper般的ODM項目,我想利用ActiveModel::Validations組件。但是,我遇到了一個問題,同時編寫測試 - 我用匿名類來構建我的測試模式,但是當涉及到運行驗證,該ActiveModel::Name類拋出一個錯誤: Class name cannot be blank. You need to supply a name argument when anonymous class given::加載ActiveModel驗證匿名類

這裏有一個簡單的代碼示例重現:

require 'active_model' 

book_class = Class.new do 
    include ActiveModel::Validations 

    validates_presence_of :title 

    def title; ""; end # This will fail validation 
end 

book_class.new.valid? # => throws error 

只有當有一個失敗的驗證程序引發異常 - 我猜測問題發生時,它會嘗試構造驗證錯誤消息。所以我的問題是:

  • 我做了很多搜索,但找不到任何人試圖做類似的事情。這是根本不可能與ActiveModel,或者有沒有我不知道的解決方法?

回答

14

ActiveModel嘗試在設置錯誤消息時獲取模型名稱(如您在此處看到的)。避開它的最快方法是給你的班級一個類別方法model_name,返回ActiveModel::Name的一個實例。

例如

require 'active_model' 

book_class = Class.new do 
    include ActiveModel::Validations 
    def self.model_name 
    ActiveModel::Name.new(self, nil, "temp") 
    end 
    validates_presence_of :title 

    def title; ""; end # This will fail validation 
end 

book_class.new.valid? # => no error 
+0

感謝,正是我想要的!我注意到'ActiveModel :: Name'可以將類名作爲參數,但沒有發現我可以通過'self.model_name'返回自己的實例。另一個不深夜編程的原因:P – motns

+0

爲什麼要從'.model_name'返回一個'ActiveModel :: Name'實例而不是一個普通字符串? –

+0

這是2年前,但是IIRC,驗證過程期望(預期?)來自該方法的ActiveModel :: Name的實例。 –

6

錯誤被拋出在ActiveModel::Namehere初始化功能。

module ActiveModel 
    class Name 
    def initialize(klass, namespace = nil, name = nil) 
     @name = name || klass.name 

     raise ArgumentError, "Class name cannot be blank. You need to supply a name argument 
     # ... 
    end 
    end 
end 

因此而不是定義一個類的方法model_name返回一個ActiveModel::Name,您可以定義一個類的方法name返回一個String

require 'active_model' 

book_class = Class.new do 
    include ActiveModel::Validations 
    validates_presence_of :title 

    def self.name 
    "Book" 
    end 

    def title; ""; end # This will fail validation 
end 

book_class.new.valid? # => false