我是一名初级 Rails 开发人员,被建议使用 Class.find(id) 来查询数据库,而不是我以前使用的 Class.find_by_id(id)。我被告知的原因是因为前者会引发异常,而后者会返回 nil。我意识到会发生这种情况,但我想知道这样做的高级概念逻辑是什么。为什么我想要例外?这是一个 Rails 标准,我总是更喜欢返回异常而不是 nil 的方法?
2 回答
您通常需要例外,因为您通常Foo.find(id)
基于来自用户的数据输入进行操作,例如单击链接。
例如,您向用户显示项目列表。有这样的链接:
http://example.com/items/100 http://example.com/items/101 http://example.com/items/102
用户单击第一个链接,并希望看到项目 100。
您的代码执行此操作:
Item.find(100)
您希望找到该项目,因为应用程序创建了项目链接。如果该项目不存在,您会感到惊讶。
(可能会出现意外情况:可能该项目已被删除,或者黑客正在发送丢失的 ID 等。使用例外可以帮助您将其作为例外情况处理。)
为此,异常优先于 nil,因为您希望代码立即失败,这样您就不会意外地将 nil 发送到其他方法。
Ruby nil 对象可能会令人困惑,因为它们的评估结果为假,还因为 nil.id == 4 因为 Ruby 使用 C 的方式。错误消息显示为“警告:Object#id 将被弃用”或“4:Fixnum 的未定义方法” ”。
一般来说,Nils 作为 Ruby 中的返回类型是有问题的。Gary Bernhardt有一个很棒的(付费)截屏视频,它解释了为什么要避免从方法返回 nil,但简而言之:当一个方法返回 nil,并且该 nil 通过一系列方法调用传递并且某处出现问题时,很难弄清楚实际问题发生在哪里。
比如说,你有这样的东西:
foo_model = MyModel.find_by_name('foo')
# some more lines of code
do_something(foo_model)
和一个方法:
def do_something(model)
# some stuff stuff
some_other_method(model)
end
现在,如果MyModel.find_by_name('foo')
返回nil
,该 nil 将继续执行而不会出现任何错误,直到它实际必须做某事。比如说,在 中some_other_method
,你实际上尝试在 上调用一些东西model
,比如说model.save
,你会得到一个错误:
undefined method 'save' for nil:NilClass (NoMethodError)
跟踪将带您备份方法调用,但它不会提及实际上有问题的行,您在其中分配MyModel.find_by_name('foo')
(评估为nil
)到foo_model
.
您可以想象,在实际应用程序中,代码可能要复杂得多,返回 nil 会使找出错误来源变得更加困难。
相反,异常会立即告诉您问题出在哪里,并且跟踪将返回到发生问题的行。这是一个原因(我想还有其他原因)为什么总的来说返回nil
不是一个好主意。
希望有帮助。