2011-03-22 83 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