Ruby:IF语句中的Nils

我正在使用的rails应用程序中有以下非常难看的ruby代码:

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

所有我想问的是是否已经定义了params [:search] [:tags_name_in],但因为params,params [:search]和params [:search] [:tags_name_in]可能都是nil,如果我使用…

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

…如果没有参数或没有搜索参数,我会收到错误。

肯定有一个更好的方法来做到这一点……建议?

如果你只是想看看它的定义为什么不保持简单并使用定义的? function?

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

Params将始终定义,因此您可以删除它。

减少您可以执行的代码量

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

如果未定义params[:search] ,则条件将短路并返回nil

你可以使用和为此。 它处理这种情况:

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

你有很多选择会返回params[:search][:tags_name_in]的值,如果params[:search]nil则返回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 ,特别是如果在未指定param时无事可做:

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

哈哈,如果你想变得可怕而且monkeypatch为零:

 class NilClass def [](key) nil end end 

如果像其他答案所说的那样,我会建议短路。

我通常最终做这样的事情:

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

虽然如果你不介意在if语句中对nils进行测试,你也可以这样做:

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

这不会引发错误,因为ruby会使&&运算符短路 。