Ruby-on-rails Rails 2:当 id 1 不存在时,Model.find(1) 给出 ActiveRecord 错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4966430/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:23:42  来源:igfitidea点击:

Rails 2: Model.find(1) gives ActiveRecord error when id 1 does not exist

ruby-on-railsruby-on-rails-2

提问by rubyprince

I am using Rails 2.3.5 and in that if I give Model.find(1)and if 1 is not in the database, it returns ActiveRecord error. Should it just be returning nilas in the case of Model.find_by_column('..')?

我正在使用 Rails 2.3.5,如果我给出Model.find(1)并且 1 不在数据库中,它会返回 ActiveRecord 错误。它应该nil像 那样返回Model.find_by_column('..')吗?

回答by Mads Mob?k

This is the expected behavior. I think David explains this the best himself, so here is a quote from Ruby, S., Thomas, D. & Hansson, D.H., 2009. Agile Web Development with Rails, Third Edition Third Edition., Pragmatic Bookshelf (p.330).

这是预期的行为。我认为 David 自己对此进行了最好的解释,因此这里引用了 Ruby, S.、Thomas, D. & Hansson, DH, 2009 年的引述。Agile Web Development with Rails,第三版 第三版。,Pragmatic Bookshelf (p.330) .

When you use a finder driven by primary keys, you're looking for a particular record. You expect it to exist. A call to Person.find(5) is based on our knowledge of the people table. We want the row with an id of 5. If this call is unsuccessful—if the record with the id of 5 has been destroyed—we're in an exceptional situation. This mandates the raising of an exception, so Rails raises RecordNotFound.

On the other hand, finders that use criteria to search are looking for a match. So, Person.find(:first, :conditions=>"name='Dave'") is the equivalent of telling the database (as a black box) “Give me the first person row that has the name Dave.” This exhibits a distinctly different approach to retrieval; we're not certain up front that we'll get a result. It's entirely possible the result set may be empty. Thus, returning nil in the case of finders that search for one row and an empty array for finders that search for many rows is the natural, nonexceptional response.

当您使用由主键驱动的查找器时,您正在查找特定记录。你期望它存在。对 Person.find(5) 的调用基于我们对 people 表的了解。我们想要 id 为 5 的行。如果这个调用不成功——如果 id 为 5 的记录已被销毁——我们处于特殊情况。这要求引发异常,因此 Rails 引发 RecordNotFound。

另一方面,使用条件进行搜索的查找器正在寻找匹配项。因此,Person.find(:first, :conditions=>"name='Dave'") 相当于告诉数据库(作为一个黑匣子)“给我名字为 Dave 的第一个人行”。这展示了一种截然不同的检索方法;我们不确定我们会得到结果。结果集完全有可能为空。因此,在查找器搜索一行的情况下返回 nil 并为搜索多行的查找器返回空数组是自然的、非异常的响应。

回答by Paul A Jungwirth

If you really don't want the exception, you can use find_by_id:

如果你真的不想要异常,你可以使用find_by_id

# @user = User.find(params[:id])    # original code
@user = User.find_by_id(params[:id])
if @user
    # found!
else
    # not found
end

This should be faster than a separate exists?check.

这应该比单独exists?检查更快。

EDIT: Note that as @Miguelgraz commented, in Rails 4 you should instead say User.find_by(id: params[:id]). Same functionality, but now the implementation won't need method_missing.

编辑:请注意,正如@Miguelgraz 所评论的,在 Rails 4 中,您应该说User.find_by(id: params[:id]). 相同的功能,但现在实现不需要method_missing.

回答by Kalendae

throwing the exception is the expected behavior.

抛出异常是预期的行为。

in fact in the normal course of events if you let the exception go unhandled your rails server will return the proper 404 page not found error.

事实上,在正常的事件过程中,如果您让异常未得到处理,您的 Rails 服务器将返回正确的 404 页面未找到错误。

if you'd like for it to return nil you can catch it yourself:

如果您希望它返回 nil,您可以自己捕获它:

begin
  @model = Model.find(id_provided)
rescue ActiveRecord::RecordNotFound => e
  @model = nil
end

回答by Shyam Habarakada

If you want the exception to be thrown in find_by_attributes flavors of the finder methods, you can use the bang! version of the method.

如果您希望在 finder 方法的 find_by_attributes 风格中抛出异常,您可以使用 bang!方法的版本。

For example,

例如,

Model.find_by_category!(a_category_value)

will throw RecordNotFound if no match is found.

如果找不到匹配项,将抛出 RecordNotFound。

I found this to be DRY in scenarios like RESTful controllers, where I have a common error handler for the exception and I want my actions to behave consistently when a resource matching the given parameters is not found.

我发现这在 RESTful 控制器等场景中是 DRY 的,在那里我有一个常见的异常错误处理程序,我希望我的操作在找不到与给定参数匹配的资源时表现一致。

回答by Abram

Rails 4 Method

Rails 4 方法

if user = User.find_by(id: params[:id]) 
  #do something with user
else
  #throw error or redirect
  raise ActiveRecord::RecordNotFound
end

回答by Alanoud Just

You can use find_bywith the required attribute (in your case the id) this will return nil instead of giving an error if the given id is not found.

您可以将find_by与所需的属性(在您的情况下为 id)一起使用,如果未找到给定的 id,这将返回 nil 而不是给出错误。

Model.find_by_id(id_value)

You could also use wherebut you have to know that where return an active record relation with zero or more records you need to use first to return only one record or nil in case zero records return.

您也可以使用where但您必须知道 where 返回一个具有零个或多个记录的活动记录关系,您需要首先使用它来仅返回一个记录或在零记录返回的情况下返回 nil。

Model.where(id: id_value).first

回答by Gaetan

You can check if the record exists before fetching it.

您可以在获取记录之前检查记录是否存在。

@model = Model.find(id) if Model.exists?(id)

回答by mohamed-ibrahim

You can simply use:

您可以简单地使用:

user = User.find(10) rescue nil