DEV Community

Discussion on: TIL: Using Different Database Connection with ActiveRecord Transactions

Collapse
edgarortegaramirez profile image
Edgar Ortega

I am almost sure you can achieve the same goal with a rescue clause.
Your communicator class should not be responsible for updating the record1 in case of failures, that's your app logic.

def call
  record1 # get record1 somehow
  ActiveRecord::Base.transaction do
    record1.update!(some_data)
    external_service_response = Communicator.call!(record1) # raises exception if response is not a success
    record2.update!(external_service_response)
  end
rescue SpecificCommunicatorError => error
  # save error can be a flag passed to this method
  record1.update(external_service_error_response) if save_error == true
  raise # without any arguments will raise the last error
end
Collapse
amrrbakry profile image
Amr El-Bakry Author

hmm, will the exception raised outside the transaction block cause the transaction to roll back?

Collapse
edgarortegaramirez profile image
Edgar Ortega • Edited on

Hmm no, the error raised inside the transaction block will force the transaction to rollback, but ActiveRecord will re-raise the same error, here I'm rescuing after the rollback has occurred, then re-raising again. If you don't need to re-raise the error again you can simply omit it.

api.rubyonrails.org/classes/Active...

Thread Thread
amrrbakry profile image
Amr El-Bakry Author

that is a great solution. I don't know why I haven't thought of that :D Thank you so much, Edgar!