在我的Rails 5 + Postgres应用程序中,我进行了如下查询:
user = User.where("name = ?", name).first.email
所以这给了我第一个用户名的电子邮件。
但是如果没有这个名字的用户存在,我会收到一个错误:
NoMethodError(未定义的方法`email'代表nil:NilClass)
在使用该方法之前,如何检查我是否有任何结果?
我可以考虑使用if-clauses进行各种方式:
user = User.where("name = ?", name).first
if user
user_email = user.email
end
但这似乎不是最优雅的方式,我相信Rails有更好的方法。
答案 0 :(得分:2)
您可以使用find_by,如果找不到任何内容,则返回对象或nil
。
user = User.find_by(name: name)
if user
...
end
话虽如此,如果你期望有多个元素,你仍然可以使用where
子句。
users = User.where(name: name)
if users.any?
user = users.first
...
end
然后还有Ruby 2.3的另一种方法,你可以做到
User.where(name: name).first&.name
如果您不确定对象是否为&
,则可以使用nil
,在这种情况下,如果找不到用户,整个语句将返回nil
。< / p>
答案 1 :(得分:1)
我经常使用try
来处理这种情况。
user = User.where("name = ?", name).first.try(:email)
它将返回电子邮件,或者如果集合为空(并且first
为nil),它将返回nil而不会引发错误。
如果找到记录但没有方法或属性存在,那么它也不会失败,所以你不太可能发现错字,但希望你的测试能够覆盖它。
user = User.where("name = ?", name).first.try(:emial)
如果您使用Ruby 2.3 &.
功能,这不是问题,因为它只适用于nil
对象......
user = User.where("name = ?", name).first&.emial
# this will raise an error if the record is found but there's no emial attrib.
答案 2 :(得分:-1)
您可以随时使用User.where("name = ?", name).first&.email
,但我不同意
user = User.where("name = ?", name).first
if user
user_email = user.email
end
特别不优雅。你可以用
之类的东西来清理它def my_method
if user
# do something with user.email
end
end
private
def user
@user ||= User.where("name = ?", name).first
# @user ||= User.find_by("name = ?", name) # can also be used here, and it preferred.
end
除非你真的认为你只会使用一次用户记录,否则你应该更倾向于使用你正在使用的任何逻辑。