2014-09-19 54 views
0

我想將錯誤消息的列表傳回給我的jQuery錯誤處理程序。我在線閱讀的大多數例子都只有一條錯誤消息,但我試圖傳回多行。將Sinatra的錯誤列表傳遞給jQuery的錯誤處理程序?

下面是一個例子:

post "/save/user" do 
    user = params["user"] 
    email = params["email"] 
    age = params["age"] 
    user = User.find(user) 

    user.update_attributes(email: email, age: age) 
    if user.valid? 
     user.save! 
    else 
     run_errors(user.errors.full_messages) 
    end 

    json :done => "You have updated your profile!" 
end 

錯誤處理:

class MyError < StandardError; end 

error MyError do 
    content_type :json 
    status 500 
    {:errors => env['sinatra.error'].message}.to_json 
end 

def run_errors(errors) 
    if not errors.empty? 
     raise MyError, errors 
    end 
end 

的jQuery:

$(".test").click(function(evn) { 
    evn.preventDefault(); 
    var form = $("form"); 
    $.post("/save/user", form.serialize(), function(done) { 
     console.log(done["done"]);   
    }) 
    .fail(errors) { 
     console.log(errors["errors"]); 
    }); 
}); 

在這個例子中,如果用戶提交錯誤的電子郵件和年齡數據,西納特拉將失敗驗證並提供user.errors.full_messages中的錯誤消息列表。這些分別是Email must be a valid email addressMust be over 18 years of age

問題出在jQuery錯誤事件處理程序。整個錯誤列表變成一個字符串,而不是錯誤的字符串列表:

{"errors":"[\"Email must be a valid email address\", \"Must be over 18 years of age\"]"} 

我可以砍JS部分和解析字符串,但並不覺得自己是一個妥善的解決辦法。我嘗試過在Sinatra中尋找錯誤處理,並且根據我的研究結果關閉了this articleSO Question,但我仍然不確定這是如何處理錯誤的。兩者都只使用一條錯誤消息,而我需要提供多條錯誤消息。

我的問題是:

  • 如何正確地從西納特拉通過我的錯誤列表jQuery的錯誤處理程序與我的當前設置?或...

  • 如果我的錯誤處理邏輯不正確,那麼從Sinatra到jquery的多個錯誤消息處理錯誤的正確邏輯是什麼?

+0

你應該改變的第一件事是http狀態碼,你使用500(內部服務器錯誤)來驗證基於用戶輸入的錯誤。正確的錯誤代碼是400(錯誤的請求)。除此之外,你可以告訴我們你的Ajax調用與觸發的錯誤處理程序嗎? – maddin2code 2014-09-24 14:06:06

回答

0

問題來自Error#message方法,它將字符串數組轉換爲字符串。一個簡單的解決方案是重寫initialize並在MyError類有一個自定義messages方法:

class MyError < StandardError 
    def initialize(messages) 
    @messages = messages 
    super(messages) 
    end 

    attr_reader :messages 
end 

然後你就可以稍微改變你的代碼中調用消息而不是信息可用時(你可以寫的東西更緊湊,但我想要的例子易於閱讀):

error MyError do 
    content_type :json 
    status 500 
    m = if env['sinatra.error'].respond_to? messages 
    env['sinatra.error'].messages 
    else 
    [ env['sinatra.error'].message ] 
    end 
    {:errors => m}.to_json 
end 

注意,當只有一個消息,我把它嵌入到一個數組,這樣的Javascript代碼總是可以期待裏面的一個或多個字符串數組。你可能想要做不同的事情。