【问题标题】:Rails 2: Model.find(1) gives ActiveRecord error when id 1 does not existRails 2:当 id 1 不存在时,Model.find(1) 给出 ActiveRecord 错误
【发布时间】:2011-06-25 09:13:21
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

你可以简单地使用:

user = User.find(10) rescue nil

【讨论】:

【解决方案2】:

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

Model.find_by_id(id_value)

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

Model.where(id: id_value).first

【讨论】:

    【解决方案3】:

    如果你真的不想出现异常,可以使用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

    【讨论】:

    【解决方案4】:

    Rails 4 方法

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

    【讨论】:

      【解决方案5】:

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

      例如,

      Model.find_by_category!(a_category_value)
      

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

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

          当您使用由 主键,您正在寻找 特定记录。你期望它 存在。对 Person.find(5) 的调用是 基于我们对人民的了解 桌子。我们想要 id 为的行 5.如果这个调用不成功——如果id为5的记录已经被 被摧毁——我们处于特殊时期 情况。这要求提高 异常,所以 Rails 引发 记录不存在。

          另一方面, 使用条件搜索的查找器 正在寻找比赛。所以, Person.find(:first, :conditions=>"name='Dave'") 是 相当于告诉数据库(如 一个黑匣子)“给我第一个人 名为 Dave 的行。”这 展现了截然不同的 检索方法;我们不确定是否会得到结果。 结果集完全有可能 可能是空的。因此,返回 nil 寻找者的案例 一行和一个空数组供查找器使用 搜索多行是 自然、无异常的反应。

          【讨论】:

          • 如果您希望在查找器方法的 find_by_attributes 风格中抛出异常,您可以使用 bang!方法的版本。例如,如果没有找到匹配项,Model.find_by_category!(a_category_value) 将抛出 RecordNotFound。我发现这在 RESTful 控制器等场景中是 DRY 的,我有一个常见的异常错误处理程序,并且我希望我的操作在找不到与给定参数匹配的资源时表现一致。
          • 每个人都在使用 Rails 时反复出现这种困惑,并得到了例外。混淆/惊讶是因为find 是一个软动词,并没有明确说明精确性或存在的预知。当然,我们现在为这个决定感到难过,但只要新人开始使用 Rails,就会提出这个问题。
          【解决方案8】:

          抛出异常是预期的行为。

          事实上,在正常的事件过程中,如果您不处理异常,您的 Rails 服务器将返回正确的 404 page not found 错误。

          如果你想让它返回 nil,你可以自己捕捉它:

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

          【讨论】:

          • 谢谢..我也发现了这个错误,我觉得它很烦人..我们可以使用Model.find_by_id(1),但我觉得它很笨拙。
          猜你喜欢
          • 2013-12-04
          • 2021-08-11
          • 2022-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-15
          相关资源
          最近更新 更多