2012-04-02 39 views
2

我對Ruby,Sinatra和DataMapper相對較新,但對DataMapper驗證錯誤有疑問。確定DataMapper驗證錯誤的源屬性

我知道你可以看到試圖通過做一些像保存一個新行與DataMapper的數據庫時出現的任何錯誤如下:

user = User.new username: 'bradleygriffith', password: 'not_my_password' 
if user.save 
    #success! 
else 
    user.errors.each do |error| 
    puts error 
    end 
end 

我想做什麼就能做的是確定在哪些屬性上發生錯誤。例如,通過這種方式,我可以將錯誤消息放在我的註冊表單的相應字段旁邊。也就是說,我想知道註冊人在之前輸入了一個無效的用戶名,顯示錯誤消息,以便我可以將該消息放在用戶名字段旁邊。

這可能嗎?

回答

2

errors對象是DataMapper::Validations::ValidationErrors一個實例,其具有on方法,該方法將返回包含所有爲你作爲參數傳遞,或者如果nil沒有錯誤的屬性的驗證錯誤消息的陣列。 (看起來這些文檔實際上並不匹配實現)。

user = User.new username: 'joe', :age => 40 

if user.save 
    #success! 
else 
    puts "Username: #{user.username} #{user.errors.on(:username)}" 
    puts "Age: #{user.age} #{user.errors.on(:age)}" 
end 

產生(用合適的驗證設置):

Username: joe ["Username must be between 4 and 20 characters long"] 
Age: 40 
1

模型類的errors屬性中的所有項都是DataMapper::Validation::Violation的實例,它們的屬性名爲attribute_name

檢出line 60datamapper source

#... 
def attribute_name 
    if @attribute_name 
    @attribute_name 
    elsif rule 
    rule.attribute_name 
    end 
end 
#... 

因此,這意味着你可以做到這一點

user = User.new username: 'bradleygriffith', password: 'not_my_password' 
if user.save 
    #success! 
else 
    user.errors.each do |error| 
     #print the name of the invalid attribute 
     puts error.attribute_name 
    end 
end 

的原因,這可能不是顯而易見的是,因爲Violation#to_s方法化名爲messageputs將調用#to_s傳遞到任何物體上它,所以當你打電話puts error它實際上打印error.message

+1

即時得到:「NoMethodError at/join。undefined method'attribute_name'for [「用戶名已被佔用」]:Array「 有什麼想法? – bradleygriffith 2012-04-02 18:31:25

+0

hmm,這樣做'放置錯誤[0] .class.name'來查看數組中的對象是什麼類型。它看起來像一個字符串,但它可能會欺騙我們。讓我知道,如果你想出這一個。 – jacobsimeon 2012-04-02 21:52:23

1

我發現,以下可以讓你獲得特定字段中的錯誤:

user.errors.keys.each do |key| 
    user.errors[key].each do |error| 
    puts "#{key} => #{error}" 
    end 
end