在Rails / Ruby中检查对象是否存在的正确方法是什么?

时间:2011-01-19 21:57:18

标签: ruby-on-rails ruby

我有很多模特和关系。由于这个事实,在视图/控制器中有很多调用,如下所示:

 @object.something.with_something.value 

链条的某些部分最终可能是零,这是完全可以的。检查终端对象是否存在的正确/清洁/快速方法是什么?

正在调用类似的内容:

 @object.something.with_something.value if defined? @object.something.with_something.value 

考虑好吗?

4 个答案:

答案 0 :(得分:8)

在本地,您需要使用&&运算符(而非defined?),但这可能会非常冗长,非常快。

所以不要这样做:

(@object && @object.something && @object.something.with_something &&
  @object.something.with_something.value)

当ActiveSupport存在时,您可以执行此操作:

@object.try(:something).try(:with_something).try(:value)

或安装invocation construction kit并使用其受保护的评估工具:

Ick::Maybe.belongs_to YourClass
maybe(@object) { |obj| obj.something.with_something.value }

答案 1 :(得分:3)

最好安排其余代码,以便最多查看链中最后一个对象的问题。

defined?不会做你想要的。可以同时defined?nil

当问题仅限于引用链中的最后一个属性时:

@object.something.with_something.value if @object.something.with_something

我可能会利用以下事实:

nil.to_a => []
nil.to_s => ''
nil.to_f => 0.0
nil.to_i => 0

因此,如果您知道某些内容是nilArray,那么通常可以通过编写以下内容来编写更好的代码而无需任何条件

something.to_a.each do |e|
  . . .

答案 2 :(得分:2)

what.you.are.doing有时被称为“火车残骸”。它也被描述为违反了得墨忒耳法。

话虽如此,我认为有一种叫做“andand”的东西可以帮助你正在做的事情。

答案 3 :(得分:0)

另一种选择是使用Null Object pattern来确保这些对象都不是零。可以说,如果您的代码将以这种方式进行链访问,那么应始终定义某些