Skip to content

Instantly share code, notes, and snippets.

@flash-gordon
Created May 30, 2016 21:47
Show Gist options
  • Save flash-gordon/64ebb082ec2a253db3a727bd7eafc393 to your computer and use it in GitHub Desktop.
Save flash-gordon/64ebb082ec2a253db3a727bd7eafc393 to your computer and use it in GitHub Desktop.
class Service
class TransactionWrapper
TransactionFailed = Class.new(StandardError)
attr_reader :sequence
delegate :append, :prepend, to: :sequence
def initialize(sequence, connection)
@sequence = sequence
@connection = connection
end
def call(*args)
result = nil
@connection.transaction do
result = sequence.call(*args)
result.or { fail TransactionFailed }
end
# We use exception here in order to avoid repeating of all this complex machinery in Sequel.transaction
rescue TransactionFailed
result
end
alias_method :[], :call
end
class << self
delegate :container, to: :MyApp
def inject
-> *values { include MyApp::Inject[*values] }
end
def define_transaction(name, container: self.container, extend: nil, &definition)
if extend
dry_transaction = extend.append(container: container, &definition)
else
dry_transaction = Dry.Transaction(container: container, &definition)
end
register_transaction(name, dry_transaction)
end
def register_transaction(name, transaction)
raise ArgumentError unless transaction.is_a?(Dry::Transaction::Sequence)
wrapped = TransactionWrapper.new(transaction, container.connection)
instance_variable_set('@%s' % name, transaction)
singleton_class.send(:attr_reader, name)
define_method(name) { wrapped }
end
end
def [](*args)
call(*args)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment