Skip to content

Instantly share code, notes, and snippets.

@louishuyng
Created October 21, 2023 05:30
Show Gist options
  • Save louishuyng/452548c0000bd5fa76f63a578e3cfd59 to your computer and use it in GitHub Desktop.
Save louishuyng/452548c0000bd5fa76f63a578e3cfd59 to your computer and use it in GitHub Desktop.
One transaction per one Object DDD
class OrdersService
def call(command)
case command
when BatchOfCommands
batch(command.commands)
when ConfirmCommand
confirm(command)
when SetDeliveryMethodCommand
set_delivery(command)
# ...
else
raise ArgumentError
end
end
private
def batch(commands)
groupped_commands = commands.group_by(&:order_number)
groupped_commands.each do |order_number, order_commands|
with_order(number) do
order_commands.each{|cmd| call(cmd) }
end
end
end
def confirm(command)
with_order(command.order_number) do |order|
order.confirm
end
end
def with_order(number)
if @order && @order.number == number
yield @order
elsif @order && @order.number != number
raise "not supported"
else
begin
order_repository.transaction do
@order = order_repository.find(number, lock: true)
yield @order
order_repository.save(@order)
end
ensure
@order = nil
end
end
end
end
batch = BatchOfCommands.new
batch.
add_command(SetDeliveryMethodCommand.new(...)).
add_command(ConfirmCommand.new(...))
OrdersService.new.call(batch)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment