我是一名初级rails开发人员,建议使用Class.find(id)来查询数据库,而不是我以前使用的Class.find_by_id(id)。我被告知的原因是因为前者会引发异常,而后者会返回 nil。我意识到这种情况会发生,但我想知道这样做的高级概念逻辑是什么。为什么我想要例外?这是一个 rails 标准,我总是更喜欢返回异常而不是 nil 的方法吗?
您通常需要异常,因为您通常根据来自用户的数据输入(例如单击链接)执行Foo.find(id)
。
例如,向用户显示项目列表。有这样的链接:
http://example.com/items/100http://example.com/items/101http://example.com/items/102
用户单击第一个链接,并期望看到项目 100。
您的代码执行以下操作:
Item.find(100)
您希望找到该项目,因为应用程序创建了项目链接。如果该项目不存在,您会感到惊讶。
(极端情况可能会令人惊讶:也许该项目被删除了,或者黑客正在发送丢失的 ID 等。使用异常可以帮助您将其作为特殊情况进行处理。
为此,异常优先于 nil,因为您希望代码立即失败,这样您就不会意外地将 nil 发送到其他方法。
Ruby nil 对象可能会令人困惑,因为它们的计算结果为 falsey,也因为 Ruby 使用 C 的方式 nil.id == 4.错误消息显示为"警告:对象 #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
不是一个好主意的原因之一(我想还有其他原因)。
希望有帮助。