检查多插入事务是否成功

Ale*_*ger 3 activerecord transactions ruby-on-rails ruby-on-rails-4

我需要在提交表单后进行一些处理,最终将多个记录保存在多个表中。因为我需要它要么全有要么全无,所以我将它包装在一个事务块中。该块似乎工作得很好,但是我不知道如何检查事务是否成功,以便我可以返回适当的响应。

    ...

      # Start a transaction block so we can back out if anything fails
      ActiveRecord::Base.transaction do

        # Journal Entry for from_account
        gle = from_account.gl_journal_entries.create(....)

        # Journal Line (x2)
        gle.gl_journal_lines.create(....)
        gle.gl_journal_lines.create(....)


        # Journal Entry for to_account
        gle = to_account.gl_journal_entries.create(....)

        # Journal Line (x2)
        gle.gl_journal_lines.create(....)
        gle.gl_journal_lines.create(....)

      end

      # return something based on success/failure of transaction

    ...
Run Code Online (Sandbox Code Playgroud)

kdd*_*isz 5

一种选择是捕获它可能会或可能不会抛出的错误。在这种情况下:

def my_method

  ...

  ActiveRecord::Base.transaction do
    # Journal Entry for from_account
    gle = from_account.gl_journal_entries.create!(....)

    # Journal Line (x2)
    gle.gl_journal_lines.create!(....)
    gle.gl_journal_lines.create!(....)


    # Journal Entry for to_account
    gle = to_account.gl_journal_entries.create!(....)

    # Journal Line (x2)
    gle.gl_journal_lines.create!(....)
    gle.gl_journal_lines.create!(....)
  end

  # this code will only get executed if the transaction succeeds

rescue Exception => ex

  # this code will only get executed if the transaction fails

end
Run Code Online (Sandbox Code Playgroud)

编辑:在这种情况下建议使用create!代替,create因为如果出现任何问题,它会抛出错误。

  • 我知道这是旧的,但为了以防万一,永远不要从异常中解救 http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby (4认同)
  • 请注意,不会在块外引发 ActiveRecord::Rollback 异常。其他例外情况会。所以也许使用 `create!` (2认同)
  • 作为@ViktorJusto 所说的后续行动,您可能需要考虑从通用 [`ActiveRecord::ActiveRecordError`](http://api.rubyonrails.org/classes/ActiveRecord/ActiveRecordError.html) 异常类中拯救像这样的情况。为完整起见,[这是其继承的异常类的列表](http://api.rubyonrails.org/files/activerecord/lib/active_record/errors_rb.html)。 (2认同)