我有很多模特和关系。由于这个事实,在视图/控制器中有很多调用,如下所示:
@object.something.with_something.value
链条的某些部分最终可能是零,这是完全可以的。检查终端对象是否存在的正确/清洁/快速方法是什么?
正在调用类似的内容:
@object.something.with_something.value if defined? @object.something.with_something.value
考虑好吗?
答案 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
因此,如果您知道某些内容是nil
或Array
,那么通常可以通过编写以下内容来编写更好的代码而无需任何条件:
something.to_a.each do |e|
. . .
答案 2 :(得分:2)
what.you.are.doing
有时被称为“火车残骸”。它也被描述为违反了得墨忒耳法。
话虽如此,我认为有一种叫做“andand”的东西可以帮助你正在做的事情。
答案 3 :(得分:0)
另一种选择是使用Null Object pattern来确保这些对象都不是零。可以说,如果您的代码将以这种方式进行链访问,那么应始终定义某些。