I have a method in a service object that composes operations that should be wrapped in a transaction. Some of these operations are also wrapped in transactions. For example:
Throwing a custom error is always a good option in case of nested transactions. Please find more detail on nested-transations-in-rails .
Another easier approach, you can raise an CustomError < StandardError. Unlike ActiveRecord::Rollback, Error will bubble up through parent transactions. You can handle it wherever required. All other inner transactions will be rolled back.
Try the below template.
ActiveRecord::Base.transacton do
ActiveRecord::Base.transacton do
raise StandardError.new
end
end
Here's how you could get failures in your nested transactions to bubble up:
User.transaction do
User.create(username: 'Kotori')
raise ActiveRecord::Rollback unless User.transaction(requires_new: true) do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
Basically, you have to raise an error in your top-level transaction for it to rollback too. To do that, you raise an error if the nested transaction returns a falsey value(nil) or a truthy value.
Hope that helps!