2010-12-12 62 views
1

我正在構建一種接收傳入電子郵件並處理電子郵件的方法。一路上有很多事情可能會阻止電子郵件成功處理。錯誤的回覆地址,錯誤的地址,空的郵件正文等。Rails 3 - 如何處理複雜的開關語句/如果語句

該代碼充滿了Switch語句(case/when/end)和If語句。我想學習一個更智能,更乾淨的方式來做到這一點。另外,一種可以跟蹤錯誤的方法,並且在最後有一個位置,它通過錯誤向用戶發送電子郵件。像這樣的事情可能與鐵軌?

@error = [] 

Case XXX 
when xxxx 
    if XXXXX 
    else 
    @error = 'You don't have permission to reply to the xxxxx' 
    end 
else 
    @error = 'Unfamilar XXXX' 
end 

然後東西在最後像...

If @errors.count > 0 
    Send the user an email letting them know what went wrong 
else 
do nothing 
end 

感謝這裏的幫助。如果你知道任何其他教程會教我如何編寫像上面這樣聰明的邏輯,那會很棒。現在我有案子/如果陳述要3層深入,很難保持直線。

謝謝

回答

2

我建議使用例外。從this tutorial開始,然後使用Google,試用和錯誤從那裏開始。

編輯:在更復雜的情況下,例外可能不是正確的工具。您可能需要使用驗證器功能來代替,例如(見其他答案),或者你可以只返回嵌套IFS的早期,而不是,例如:

unless sender_valid? 
    @error = "Sender invalid" 
    return 
end 
unless subject_valid? 
    @error = "Invalid command" 
    return 
end 
# normal no-errors flow continues here... 
+0

我非常喜歡例外。在大多數情況下,該方法的隱式退出正是您想要的。 – aceofspades 2010-12-12 18:55:22

+0

只有在處理真正的異常時才使用異常。如果它是預期的流量,則不要使用例外。例如:用戶輸入的任何數據通常都是錯誤的,絕對不應該有例外處理。清理代碼的真正方法是將其分成小塊邏輯塊(方法和類)。嵌套case和ifs通常是一個設計問題。在這種情況下使用例外只是一個繃帶,但不是真正的解決方案。 – iain 2010-12-12 19:44:22

+0

如果您有一個複雜的案例,最好將其抽象爲驗證器函數而不是使用異常。權衡你的選擇。 – moeffju 2010-12-12 19:54:17

1

當事情是不對的,你可能會引發錯誤。然後在你的方法結束時抓住它。

http://phrogz.net/programmingruby/tut_exceptions.html

爲了使您的代碼的可讀性,並沒有很多的開關,如果/ then語句,你可以創建一個驗證某些方面和從你的主要錯誤檢查方法調用它們單獨的方法。

+0

使用異常日誌可能會減慢你的應用程序17倍 – mpapis 2010-12-12 18:42:01

+0

@mpapis:你確定這是真的Ruby?你能給一些參考嗎? – klew 2010-12-12 18:51:17

+0

http://rpheath.com/posts/237-raising-custom-exceptions-in-rails - 在評論中 – mpapis 2010-12-12 18:55:54

3

首先,我只是分配一個符號給每個錯誤消息作爲一個簡單的哈希:

ErrorsDescription = { 
    :first => "First error", 
    :second => "Second error", 
    ... 
} 

而且使用的符號,而不是字符串。

然後,你的if和switch語句。基本我不能真正幫助你,因爲我沒有看到你有什麼樣的條件陳述。你在檢查什麼?爲什麼你有3個深度的條件?大概你可以使用if和switch來簡化它 - 所以這是我對這個問題的第一個答案。另一種解決方案可能是寫一個簡單的方法來提高可讀性,所以你可以這樣寫:

if @email.has_wrong_reply_to_address? 
    @errors << :wrong_reply_to_address 
else 
    ... 
end 

而且,@mpapis建議,您可以使用Rails的建立驗證系統,而不是作爲ActiveRecord而是作爲ActiveModelHere你有一些例子如何做到這一點,以及它是如何工作的(也看看here)。當然,您可能需要編寫自定義驗證,但它們只是簡單的方法。一旦你做到以上所有的工作,你可以使用:

@email.valid? 

如果不是的話,你把所有的錯誤在哈希:

@email.errors 

就像普通ActiveRecord對象。

然後,您可以用send_error_email方法擴展您的Emial類,該方法在發生錯誤時發送電子郵件。

編輯:

這是關於您在評論中附加的新信息。

您不必使用嵌套的ifs並在此切換。你可以把它看起來像這樣:

def is_this_email_valid? 
    if !email_from_user_in_system? 
    @errors << :user_not_in_system 
    return false 
    end 
    if comment_not_exists? 
    @errors << :comment_not_exists 
    return false 
    end 
    if user_cannot_comment_here? 
    @errors << :permision_error 
    return false 
    end 
    ... 
    true 
end 

然後你可以使用它:

if [email protected]_this_email_valid? 
    @email.send_error_mail 
end 
+0

謝謝。原因它走三級深。首先,我檢查以確保電子郵件來自系統中的用戶。然後我確定他們正在回覆存在的評論。然後我確定他們有權回覆該評論。然後我確保評論不是空白/零。合理? – AnApprentice 2010-12-12 19:22:51

+0

@AnApprentice:是的,這很有道理。但爲什麼要通過郵件回覆評論?你不能使用html表單嗎? – klew 2010-12-12 19:47:07

+0

@AnApprentice:你爲什麼不早點退出?例如。 「如果郵件不是來自有效用戶,則返回錯誤」。 – moeffju 2010-12-12 19:55:34