2011-03-22 81 views
8

我曾經在一個Rails應用程序下面的非常難看Ruby代碼我工作:紅寶石:尼爾斯在IF語句

if params.present? 
    if params[:search].present? 
    if params[:search][:tags_name_in].present? 
     ... 
    end 
    end 
end 

所有我想要問的是是否PARAMS [:搜索] [ :tags_name_in]已定義,但由於參數,可以而params [:搜索],而params [:搜索] [:tags_name_in]可能全部是零,如果我用...

if params[:search][:tags_name_in].present? 

...我如果沒有參數或沒有搜索參數,會得到一個錯誤。

當然,必須有更好的方法來做到這一點......建議?

+0

的說明哪些回答我選擇的是:在我的應用程序的這個條件是否返回'nil'或'false'並不重要,':tags_name_in'不是空白也不重要,我只需要測試':tags_name_in'是否被定義而不會引發錯誤。所以,對於我的情況,我喜歡Will Ayd給出的'defined?'方法。不過,我認爲邁克劉易斯的方法可能會對其他可能需要避免將零價值轉化爲條件的人更有用。所以,請看這兩個答案,並決定這是否在你的情況。 – Andrew 2011-03-22 17:03:41

回答

10

如果你只是想看看它的定義爲什麼不保持簡單並使用定義?功能?

if defined?(params[:search][:tags_name_in]) 
+0

這是一個很好:) – fl00r 2011-03-22 16:11:52

+2

這不等同於他最初詢問的代碼。 'defined?'將返回true,如果一個變量已經被初始化,即使它被設置爲'nil'。 'present?'使用'blank?'檢查,所以'nil'將返回false。 – 2011-03-22 16:14:40

+0

當然,但問題是他只是問是否已經定義 - 這將做什麼。 – 2011-03-22 16:16:02

6

參數總是被定義的,所以你可以刪除它。

爲了減少代碼量,你可以做

if params[:search] && params[:search][:tags_name_in] 
    #code 
end 

如果沒有定義params[:search],病情會短路並返回nil

+0

我編輯表示返回'nil',而不是'false'。 – 2011-03-22 16:42:03

+0

啊,很好。謝謝。 – 2011-03-22 16:45:29

+1

你假設這個代碼是在一個鐵軌控制器。在某些類中,params可能是不確定的或無。 – 2015-03-13 06:26:01

0

我通常最終會做這樣的事情:

if params.has_key?(:search) && params[:search].has_key?(:tags_name_in) 
... 

end 

但如果你在不介意對尼爾斯測試你的if語句也可以這樣做:

if params[:search] && params[:search][:tags_name_in] ... 

這不會拋出一個錯誤,因爲紅寶石short-circuits & &運算符。

4

您可以使用andand。它處理這個確切的情況:

if params[:search].andand[:tags_name_in].andand.present?

+0

這是一個非常酷的寶石,謝謝你的提示! – Andrew 2011-03-22 16:54:40

+0

+1如果只有每個人都使用並且在這些情況下(儘管我更喜歡寫等價的「可能」)而不是條件和更多的條件(或醜陋的「嘗試」) – tokland 2011-03-22 17:22:44

3

哈哈,如果你想成爲可怕的,猴補丁零:

class NilClass 
    def [](key) 
    nil 
    end 
end 

我會建議短路,如果像其他的答案表明,雖然。

+0

爲什麼這麼糟糕?對我來說似乎很棒。 – 2015-03-13 06:26:36

4

你有很多的選擇,將返回params[:search][:tags_name_in]值或nil如果params[:search]nil

清除,但冗長:

params[:search] && params[:search][:tags_name_in] 

使用try(從active_support):

params[:search].try(:[], :tags_name_in) 

使用救援:

params[:search][:tags_name_in] rescue nil 

使用fetch

params.fetch(:search, {})[:tags_name_in] 

注意fetch可有時被用來避免if完全,特別是如果有什麼不指定參數是什麼時候做:

def deal_with_tags 
    MyModel.where :tags => params.fetch(:search){ return }[:tags_name_in] 
end 
+0

+1。我正準備發佈'try'和'fetch'解決方案。在Ruby中查找異常處理的代價後,我停止使用內聯'rescue'。 – 2011-03-22 17:02:48

+0

獲取方法看起來非常有用,我會查找它,並且我可能能夠在幾個地方使用它! – Andrew 2011-03-22 17:05:22

+0

OP需要處理參數本身爲零!在這種情況下,這個答案仍然會導致錯誤。 – 2015-03-13 06:24:48