Created
October 24, 2023 15:28
-
-
Save louishuyng/b6f58c8c3462d3e37868d76e3471db42 to your computer and use it in GitHub Desktop.
Aggregate Root
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Product | |
include AggregateRoot | |
def register(store_id:, sku:) | |
apply(ProductRegistered.new(data: { | |
store_id: store_id, | |
sku: sku, | |
})) | |
end | |
def supply(quantity) | |
apply(ProductSupplied.new(data: { | |
store_id: @store_id, | |
sku: @sku, | |
quantity: quantity, | |
})) | |
end | |
def reserve(quantity:, order_number:) | |
unless @quantity_available >= quantity | |
raise QuantityNotAvailable | |
end | |
apply(ProductReserved.new(data: { | |
store_id: @store_id, | |
sku: @sku, | |
quantity: quantity, | |
order_number: order_number, | |
})) | |
end | |
private | |
def apply_strategy | |
->(_me, event) do | |
case event | |
when ProductRegistered | |
registered(event) | |
when ProductSupplied | |
supplied(event) | |
when ProductReserved | |
reserved(event) | |
else | |
raise "Missing handler for #{event}" | |
end | |
end | |
end | |
def registered(event) | |
@store_id = event.data.fetch(:store_id) | |
@sku = event.data.fetch(:sku) | |
@quantity_available = 0 | |
@quantity_reserved = 0 | |
@quantity_shipped = 0 | |
end | |
def supplied(event) | |
@quantity_available += event.data.fetch(:quantity) | |
end | |
def reserved(event) | |
quantity = event.data.fetch(:quantity) | |
@quantity_available -= quantity | |
@quantity_reserved += quantity | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
repository = AggregateRoot::Repository.new(Rails.configuration.event_store) | |
stream = "Product$#{product_id}" | |
product = repository.load(Product.new, stream) | |
product.reserve( | |
quantity: quantity, | |
order_number: order_number | |
) | |
repository.store(product, stream) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment