2

我是一名初级 Rails 开发人员,被建议使用 Class.find(id) 来查询数据库,而不是我以前使用的 Class.find_by_id(id)。我被告知的原因是因为前者会引发异常,而后者会返回 nil。我意识到会发生这种情况,但我想知道这样做的高级概念逻辑是什么。为什么我想要例外?这是一个 Rails 标准,我总是更喜欢返回异常而不是 nil 的方法?

4

2 回答 2

4

您通常需要例外,因为您通常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 的未定义方法” ”。

于 2013-01-26T06:00:04.433 回答
1

一般来说,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不是一个好主意。

希望有帮助。

于 2013-01-26T05:59:51.870 回答