Today I Learned

hashrocket A Hashrocket project

Managing Return Value of ActiveRecord Transactions

I recently ran into a situation where I wanted to know the return state of a transaction in ActiveRecord. Basically, I wanted to know if it succeeded or failed, then return true/false.

There's 3 scenarios to keep in mind to when trying to use this approach:

  1. Transaction succeeds - the last line of the transaction is the return
    class TestModel
     def save
       result =
         ActiveRecord::Base.transaction do
           SomeModel.last.touch
         end
    
       result
     end
    end
    
    > TestModel.new.save
    => true
  2. Transaction rollbacks - transactions handle ActiveRecord::Rollback by default, so the transaction block returns nil
    class TestModel
     def save
       result =
         ActiveRecord::Base.transaction do
           raise ActiveRecord::Rollback
         end
    
       result
     end
    end
    
    > TestModel.new.save
    => nil
  3. Other Errors - any errors raised inside the transaction will be raised by the block
    class TestModel
     def save
       result =
         ActiveRecord::Base.transaction do
           raise ActiveRecord::Rollback
         end
    
       result
     end
    end
    
    > TestModel.new.save
    StandardError: StandardError from .....

Putting it all together now, we can return a true/false for all scenarios -

class TestModel
    def save
      result =
        ActiveRecord::Base.transaction do
          SomeModel.new(attrs).save!
          OtherModel.new(other_attrs).save!
        end

      result

      did_save = !!result
      did_save
    rescue => e
       false
    end
end
See More #rails TILs
Looking for help? Hashrocket has been an industry leader in Ruby on Rails since 2008. Rails is a core skill for each developer at Hashrocket, and we'd love to take a look at your project. Contact us and find out how we can help you.