2017-07-26 46 views
-1

运行如下语句:红宝石:投掷未定义的方法错误

self.user.email || self.organization.email || nil 

红宝石引发错误undefined method 'email' for nil:NilClass,但它应该只是返回nil代替。我在这里做错了什么?

它在某些情况下user因为出现|| organizationnil

+0

是的,你说得对,是某些情况下'用户== nil'或'组织== nil' –

+0

@IgorDrozdov但我希望它只是跳转到下一个选项。 – jonhue

回答

3

self.user.email,如果self.user是n,那么你不能打电话给email就可以了。

如果你使用Ruby 2.3或更高版本,可以使用safe navigation operator

self.user&.email || self.organization&.email 

注意|| nil末可能是unneccesary。

如果你不希望引入一个依赖于Ruby的2.3或更新版本,你可以使用Object#try从的ActiveSupport(包括使用Rails):

self.user.try(:email) || self.organization.try(:email) 
+0

不知道安全导航操作符 - 很好! – jonhue

+1

@jonhue也注意到,'self'这里是不必要的,除非你除了名称相同的方法定义的本地变量'user'。 –

0

当用户/组织为零是错误发生。它试图从一个无类的电子邮件。所以你可以添加条件,如user.present? || organization.present?。通过条件后获得电子邮件。如果条件失败,则为零。

+0

没有条件就不可能? – jonhue

+1

不一定。你可以使用“try”,就像@max所说的那样。 –

2

下面的代码做你期待什么:

user && user.email || organization && organization.email 

如果您使用ruby >= 2.3.0,还有空的传播特点:

user&.email || organization&.email 
+0

另一种选择是做user.try(:电子邮件)|| organization.try(:电子邮件)。 https://apidock.com/rails/NilClass/try还自我可能是多余的 –

+0

@NatanRubinstein提供我们开发Rails应用程序。然后我会建议使用'NilClass#try!' –

0

只是出于好奇:

[user, organization].compact.map(&:email).compact.first 

,或者对于Ruby2.3 +

[user, organization].compact.map(&:email).detect(&:itself) 
相关问题