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:
-
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
-
Transaction rollbacks - transactions handle
ActiveRecord::Rollback
by default, so the transaction block returns nilclass TestModel def save result = ActiveRecord::Base.transaction do raise ActiveRecord::Rollback end result end end > TestModel.new.save => nil
-
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
Tweet