我想返回mycollection.first.user.name
,但mycollection
或mycollection.first
可能为零。以下代码很丑陋,但有效:
if mycollection && mycollection.first && mycollection.first.user
mycollection.first.user.name
end
什么是红宝石方式?
我想返回mycollection.first.user.name
,但mycollection
或mycollection.first
可能为零。以下代码很丑陋,但有效:
if mycollection && mycollection.first && mycollection.first.user
mycollection.first.user.name
end
什么是红宝石方式?
如果您碰巧使用的是 Rails,它会添加一个方法来Object
调用try
,这可能会有所帮助:
mycollection.try(:first).try(:user).try(:name)
这将依次调用first
、user
和,但如果链中的任何值是,它只会返回而不抛出异常。name
nil
nil
如果你不使用 Rails,你可以很容易地自己定义它:
class Object; def try(method,*args,&block); send(method,*args,&block); end end
class NilClass; def try(method,*args,&block); nil; end end
有些人不太热衷于 try(),但它肯定是您可能喜欢的一种方法。
name = mycollection.try(:first).try(:user).try(:name)
如果任何内容为 nil,则 name 将为 nil,否则将返回 name 的值。
此外,您可能想要重构您的模型,以便您可以这样调用:
item.user_name
class ItemClass
def user_name
user.try(:name)
end
end
item 是集合中的第一个。
name = if mycollection && item = mycollection.first
item.user_name
end
在纯 Ruby 中,你可以这样做:
if mycollection && mycollection.first.respond_to?(:user)
mycollection.first.user.name
end
那是因为如果mycollection
是一个空数组,mycollection.first
将返回 nil:
irb(main):002:0> nil.respond_to?(:user)
false