2011-08-13 73 views
3

我正在使用Ruby on Rails 3.0.9,並試圖驗證嵌套模型。假設我運行驗證爲「主」模式,對於嵌套模型,我得到以下產生一些錯誤:嵌套模型錯誤消息

@user.valid? 

@user.errors.inspect 
# => {:"account.firstname"=>["is too short", "can not be blank"], :"account.lastname"=>["is too short", "can not be blank"], :account=>["is invalid"]} 

怎麼可以看到RoR的框架創建具有以下鍵的errors哈希:account.firstnameaccount.lastnameaccount。由於我想通過處理那些包含CSS屬性的JavaScript屬性(我使用jQuery)來處理那些錯誤鍵值對,從而在前端內容上顯示錯誤消息,所以我想「準備」該數據並將這些鍵更改爲account_firstnameaccount_lastnameaccount(注意:我用_字符替換.)。

如何將密鑰值從例如account.firstname更改爲account_firstname

而且,大部分重要,我應該如何處理這種情況呢?我試圖做一個「好」的方式來處理嵌套的模型錯誤?如果不是,那麼通常的最佳方法是什麼?

回答

2

Rails錯誤散列的一些創意修補會讓你實現你的目標。在config/initalizers創建初始,讓我們把它叫做errors_hash_patch.rb並把下面的變量:

ActiveModel::Errors.class_eval do 
    def [](attribute) 
    attribute = attribute.to_sym 
    dotted_attribute = attribute.to_s.gsub("_", ".").to_sym 
    attribute_result = get(attribute) 
    dotted_attribute_result = get(dotted_attribute) 
    if attribute_result 
     attribute_result 
    elsif dotted_attribute_result 
     dotted_attribute_result 
    else 
     set(attribute, []) 
    end 
    end 
end 

所有你在這裏做的是簡單地重寫訪問方法[]嘗試有點困難。更具體地說,如果你正在尋找的鍵已經強調,它會嘗試按原樣查找它,但是如果它找不到任何東西,它也會用點替換所有下劃線,並嘗試查看它。除此之外,其行爲與常規的[]方法相同。例如,假設你有一個錯誤的散列像一個從你的例子:

errors = {:"account.firstname"=>["is too short", "can not be blank"], :"account.lastname"=>["is too short", "can not be blank"], :account=>["is invalid"]} 

下面是一些你可以訪問它的方式和回來的結果:

errors[:account] => ["is invalid"] 
errors[:"account.lastname"] => ["is too short", "can not be blank"] 
errors[:account_lastname] => ["is too short", "can not be blank"] 
errors[:blah] => [] 

我們不不會改變密鑰存儲在錯誤散列中的方式,所以我們不會意外中斷可能依賴散列格式的庫和行爲。我們所做的就是在我們如何訪問哈希中的數據方面有點聰明。當然,如果你想改變哈希中的數據,那麼模式是相同的,你只需要重寫[]=方法,並且每當rails試圖存儲帶有點的鍵時,只需將點改爲下劃線即可。

至於你的第二個問題,即使我已經告訴你如何去做你所問的問題,但總的來說,最好的辦法是遵循鋼軌試圖做的事情,而不是試圖彎曲鋼軌你的意願。在你的情況下,如果你想通過javascript顯示錯誤消息,大概你的JavaScript將有權訪問錯誤數據的哈希值,那麼爲什麼不用JavaScript來調整這些數據,使其成爲你需要的格式。或者,您可以克隆控制器內的錯誤數據並在其中調整(在JavaScript訪問之前)。如果你不瞭解你的情況(你如何編寫你的表格,你的驗證JS試圖做什麼等等),那麼很難提供建議,但這些都是一些一般性的指導方針。

4

我做了一個快速的關注,顯示了嵌套模型完全錯誤信息:

https://gist.github.com/4710856

#1.9.3-p362 :008 > s.all_full_error_messages 
    # => ["Purchaser can't be blank", "Consumer email can't be blank", "Consumer email is invalid", "Consumer full name can't be blank"] 
1

我有AngularJs同樣的問題,所以我決定重寫了該as_json方法ActiveModel::Errors類在初始化程序中調用active_model_errors.rb,以便它可以替換._

這裏是初始值設定項代碼:

module ActiveModel 
    class Errors 
    def as_json(options=nil) 
     hash = {} 
     to_hash(options && options[:full_messages]).each{ |k,v| hash[k.to_s.sub('.', '_')] = messages[k] } 
     hash 
    end 
    end 
end 

我希望它可以爲別人