我该怎么写:
if @parent.child.grand_child.attribute.present?
do_something
没有繁琐的零检查以避免异常:
if @parent.child.present? && @parent.child.grandchild.present? && @parent.child.grandchild.attribute.present?
谢谢。
答案 0 :(得分:4)
Rails有object.try(:method)
:
if @parent.try(:child).try(:grand_child).try(:attribute).present?
do_something
答案 1 :(得分:3)
答案 2 :(得分:3)
您可以通过将中间值分配给某个局部变量来稍微减少它:
if a = @parent.child and a = a.grandchild and a.attribute
答案 3 :(得分:2)
为了好玩,你可以使用折叠:
[:child, :grandchild, :attribute].reduce(@parent){|mem,x| mem = mem.nil? ? mem : mem.send(x) }
但是使用andand可能更好,或ick,我非常喜欢并且有try
和maybe
等方法。
答案 4 :(得分:0)
如果要检查的属性始终相同,请在@parent中创建方法。
def attribute_present?
@parent.child.present? && @parent.child.grandchild.present? && @parent.child.grandchild.attribute.present?
端
或者,创建has_many :through
关系,以便@parent
可以转到grandchild
,以便您可以使用:
@parent.grandchild.try(:attribute).try(:present?)
注意:present?
不仅适用于nil,还会检查空值''
。如果只是零检查,你可以@parent.grandchild.attribute
答案 5 :(得分:0)
你只能抓住例外:
begin
do something with parent.child.grand_child.attribute
rescue NoMethodError => e
do something else
end
答案 6 :(得分:0)
我想你可以使用delegate
方法做到这一点,因为你会像......
@parent.child_grand_child_attribute.present?
答案 7 :(得分:0)
您好,您可以在此处使用带有救援选项的标志变量
flag = @parent.child.grand_child.attribute.present? rescue false
if flag
do_something
end
答案 8 :(得分:0)
你可以这样做:
Optional = Struct.new(:value) do
def and_then(&block)
if value.nil?
Optional.new(nil)
else
block.call(value)
end
end
def method_missing(*args, &block)
and_then do |value|
Optional.new(value.public_send(*args, &block))
end
end
end
您的支票将成为:
if Optional.new(@parent).child.grand_child.attribute.present?
do_something
答案 9 :(得分:0)
所有这些答案都是过时的,所以我认为我应该分享更多现代选择。
如果您获得的关联可能不存在:
@parent&.child&.grand_child&.attribute
如果您要查找可能不存在的密钥的哈希值:
hash = {
parent_key: {
some_other_key: 'a value of some sort'
},
different_parent_key: {
child_key: {
grand_child: {
attribute: 'thing'
}
}
}
}
hash.dig(:parent_key, :child_key, :grandchild_key)
如果子代,孙代或属性不存在,则这两种方法都会正常返回nil