Skip to content

Instantly share code, notes, and snippets.

@thil
Created October 3, 2023 22:39
Show Gist options
  • Save thil/f83c7ab271223a72cde2214e14e3a073 to your computer and use it in GitHub Desktop.
Save thil/f83c7ab271223a72cde2214e14e3a073 to your computer and use it in GitHub Desktop.
Add wrapped db transaction to dry transactions
# frozen_string_literal: true
module DbTransactionAdapter
# Add the ability to wrap number of steps into database transaction
#
# @example
# db_transaction, :db do
# step :validate
# check :clear
# step :create # failure here will rollback previous side effects
# end
#
# You can pass step_args using
# ServiceClass.new.with_step_args(
# db: [
# step_args: {
# validate: [
# config: { seconds: 100, bypass: '123456' },
# ],
# create: [
# expiry: 1.day,
# secret: 'secret',
# ]
# }
# ]
# ).call({ token: email, code: '123456' })
#
def db_transaction(key, &)
step key
define_method key do |params, step_args: {}|
result = nil
ActiveRecord::Base.transaction do
klass = Class.new(self.class)
klass.instance_exec(&)
new_klass = klass.new.with_step_args(**step_args)
result = new_klass.stack.call(Success(params))
raise ActiveRecord::Rollback if result.failure?
end
result
rescue ActiveRecord::Rollback
result
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment