2012-11-06 30 views
2

我的web應用程序失敗的最常見原因之一是因爲用戶有時缺少某個視圖期望的特定屬性。例如,我的應用程序中的大多數用戶在我們的系統中都有教育(學校,學位等)條目,但有些用戶卻沒有。假設我的觀點看起來是這樣的:異常處理:「未定義的方法____'爲零:NilClass」

<% @educations.each do |education| %> 
    <%= education.school %> 
    <%= education.degree %> 
<% end %> 

我想避免「寵物小精靈」的異常處理,並認爲必須有一個更好的辦法解決處理一個「爲無未定義的方法`度」:NilClass」錯誤在用戶在我們的數據庫中沒有教育條目的情況下。這看起來像一個醜陋/乏味的修復:

<% @educations.each do |education| %> 
    <% if education.school %> 
    <%= education.school %> 
    <% end %> 
    <% if education.degree %> 
    <%= education.degree %> 
    <% end %> 
<% end %> 

任何輸入表示讚賞。謝謝!

+1

看起來你遇到的問題並不是「度數」是零,而是你的「教育」實例之一是零('nil:NilClass'沒有定義方法'程度')。 '@ educations'從哪裏來? –

回答

0

只要你知道你的工作不會是零的第一個對象,最簡單的方法是隻做到這一點:

- @educations.each do |education| 
    = education.try :school 
    = education.try :degree 

#try方法是非常方便的。您也可以撥打.to_s在任何你認爲可能是零,即:

- @educations.each do |education| 
    = education.school.to_s 
    = education.degree.to_s 

這將尼爾斯轉換爲空字符串。這在IMO的視圖中並沒有那麼有用,但如果您有希望是字符串並且可能爲空的輸入,那麼它會派上用場。即一種方法,如:

def put_in_parenthesis(string) 
    "(" + string.to_s + ")" 
end 
0

您在這裏有幾個選項。

最容易實現的是try method。它用於像這樣:

<%= education.try(:degree) %> 

的問題是,try()被視爲a bit of an anti-pattern。正如參考文獻指出的那樣,您可以通過類似的方式實現類似的功能:

<%= education && education.degree %> 

在我看來,這在智力上並沒有太大差異。處理這個更簡潔一點的流行方式是Null Object pattern,它基本上是一個定義了中性(「null」)行爲的對象。

+0

FWIW他在上面的例子中並沒有問'如果教育',即使他做了'如果教育&& education.degree; education.degree;結局「,這仍然是他要求不必做的事情。我認爲對於非常簡單的應用程序,如視圖,'#try'是完全合適的。 – Andrew

+0

他不必將其包裝在if中,它會返回其評估的最後結果。例如,啓動irb並嘗試''spice'&&'nice'&& true &&'rice'&& nil'和''spice'&&'nice'&& true&''rice''。只要你願意,你可以將它鏈接起來,所以它可以處理諸如'<%= education && education.degree && education.degree.date%>'之類的東西。 (我知道你可以鏈接嘗試,也可以發送它的參數。)就個人而言,我認爲這最好通過使用空對象模式來解決,除了在微不足道的情況下(這就是我包括它的原因)。我認爲嘗試的大多數用法可以通過良好的架構來避免 –

+0

我的不好,我誤解了你的答案。感謝您在評論中詳細說明。 – Andrew

相關問題