5

I need to do some processing after a form is submitted that ends up saving multiple records in multiple tables. Since I need it to be all-or-nothing, I wrapped it in a transaction block. The block seems to work just fine, however I don't know how I can check whether or not the transaction was successful so I can return an appropriate response.

    ...

      # 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

    ...
Alec Sanger
  • 4,442
  • 1
  • 33
  • 53

1 Answers1

6

One option is to catch the error that it may or may not be throwing. In this case:

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

Edit: using create! instead of create is recommended in this instance because it will throw an error if anything goes wrong.

kddeisz
  • 5,162
  • 3
  • 21
  • 44
  • 2
    Note that ActiveRecord::Rollback exception will not be raised outside the block. Other exceptions will though. So perhaps use `create!` – Philip Hallstrom Oct 30 '13 at 18:22
  • 4
    i know this is old, but just in case, never rescue from Exception http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby – Viktor Justo Oct 03 '16 at 02:57
  • 3
    As a follow-up to what @ViktorJusto said, you might want to consider rescuing from the generic [`ActiveRecord::ActiveRecordError`](http://api.rubyonrails.org/classes/ActiveRecord/ActiveRecordError.html) exception class for situations like this. For completeness, [this is a list of its inherited exception classes](http://api.rubyonrails.org/files/activerecord/lib/active_record/errors_rb.html). – pjrebsch Apr 20 '17 at 18:58