Skip to content

Instantly share code, notes, and snippets.

@mariuszkapcia
Last active January 28, 2019 17:54
Show Gist options
  • Save mariuszkapcia/7be39a4022edd566752d6ce9ff58731f to your computer and use it in GitHub Desktop.
Save mariuszkapcia/7be39a4022edd566752d6ce9ff58731f to your computer and use it in GitHub Desktop.
AggregateRoot pattern with extracted load method, store method, version attribute, and unpublished_events array to AggregateRepository.
class AggregateRepository
def load
@event_store.read.stream(@stream_name).forward.each do |event|
@aggregate.apply(event)
@version += 1
end
end
def store(events)
events.each do |event|
@event_store.publish(
event,
stream_name: @stream_name,
expected_version: @version
)
@version += 1
end
end
private
def initialize(aggregate, stream_name, event_store)
@aggregate = aggregate
@stream_name = stream_name
@event_store = event_store
@version = -1
end
end
module MyAggregateRoot
MissingEventInApplyStrategy = Class.new(StandardError)
def default_apply_strategy(event)
"apply_#{event.class.to_s.demodulize.underscore}"
end
def apply_strategy
{}
end
def apply(*events)
events.each do |event|
mutate_state(event)
end
events
end
def mutate_state(event)
begin
callback_method = if apply_strategy.present?
apply_strategy.fetch(event.class.to_s.demodulize.underscore.to_sym)
else
default_apply_strategy(event)
end
rescue KeyError
raise MissingEventInApplyStrategy.new("#{event.class} is missing in apply_strategy.")
end
send(callback_method, event)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment