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

时间:2011-02-11 07:01:18

标签: ruby-on-rails ruby-on-rails-2

我正在使用Rails 2.3.5,如果我给Model.find(1)并且如果1不在数据库中,则返回ActiveRecord错误。是否应该像nil一样返回Model.find_by_column('..')

8 个答案:

答案 0 :(得分:56)

这是预期的行为。我认为大卫自己解释得最好,所以这里引用了Ruby,S.,Thomas,D。& Hansson,D.H.,2009。Agile Web Development with Rails,Third Edition Third Edition。,Pragmatic Bookshelf(p.330)。

  

使用由...驱动的取景器时   主键,你正在寻找一个   特别记录。你期待它   存在。对Person.find(5)的调用是   基于我们对人的了解   表。我们想要一个id为的行   5.如果此调用不成功 - 如果id为5的记录已经成功   被毁 - 我们是一个例外   情况。这要求提高   一个例外,所以Rails加注   记录不存在。

     

另一方面,   使用标准进行搜索的查找程序   正在寻找一场比赛。所以,   Person.find的(:第一,   :conditions =>“name ='Dave'”)是   相当于告诉数据库(如   一个黑盒子)“给我第一个人   名为Dave的行。“这   表现出截然不同的   检索方法;我们前面不确定我们会得到一个结果。   结果集完全可能   可能是空的。因此,返回nil in   搜索的发现者的情况   查找器的一行和一个空数组   搜索多行是   自然的,非感性的反应。

答案 1 :(得分:24)

如果您真的不想要例外,可以使用find_by_id

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

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

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

答案 2 :(得分:5)

抛出异常是预期的行为。

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

如果你想让它返回零,你可以自己抓住它:

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

答案 3 :(得分:2)

如果你想在finder方法的find_by_attributes风格中抛出异常,你可以使用爆炸!该方法的版本。

例如,

Model.find_by_category!(a_category_value)
如果找不到匹配项,

将抛出RecordNotFound。

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

答案 4 :(得分:1)

Rails 4方法

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

Model.find_by_id(id_value)

你也可以使用 where ,但你必须知道,如果返回与零个或多个记录的活动记录关系,你需要首先使用它来返回一个记录,如果零记录返回则需要nil。

Model.where(id: id_value).first

答案 7 :(得分:-1)

您可以简单地使用:

user = User.find(10) rescue nil