Ruby on Rails:如何捕获 ActiveRecord::Rollback?

ran*_*its 5 ruby ruby-on-rails

在我的控制器中,我的代码如下所示:

    @mymodel.transaction do 
      for a in arr
        @mymodel.some_method(a)
      end
    end
Run Code Online (Sandbox Code Playgroud)

在 @mymodel#some_method 中,我可以抛出一个ActiveRecord::Rollback异常,该异常在数据库中执行它需要执行的操作,但是我只是得到一个 HTTP 500,并且无法捕获异常以让用户以优雅的方式知道出了什么问题。

我尝试将 @mymodel.transaction do 包装在开始/救援块中,但这也行不通。捕获异常的最佳方法是什么,以便我可以向用户呈现正确的视图?

rjk*_*rjk 3

ActiveRecord::Base文档中:

通常,引发异常将导致该transaction方法回滚数据库事务传递异常。但是,如果引发 ActiveRecord::Rollback 异常,则数据库事务将回滚,而不传递异常。

一个小例子:

class ThrowController < ApplicationController
  def index
      status = ActiveRecord::Base.connection.transaction do
        raise ActiveRecord::Rollback.new
      end

      Rails.logger.info "followed transaction"
  end
end
Run Code Online (Sandbox Code Playgroud)

然后:

>> c = ThrowController.new.index
=> "followed transaction \n"
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,ActiveRecord:::Rollback异常被transaction块吞没了。

在我看来,您的代码似乎还发生了一些我们不知道的事情。