Last active
January 28, 2019 18:01
-
-
Save mariuszkapcia/ce1afab1cc51633e112f8574aa1905c7 to your computer and use it in GitHub Desktop.
AggregateRoot pattern with extracted events and persistence. Loading and storing of an aggregate is done by DeveloperStore service.
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
def register(cmd) | |
ActiveRecord::Base.transaction do | |
with_developer(cmd.developer_uuid) do |developer| | |
developer.register | |
DeveloperRegistered.strict(data: { | |
developer_uuid: cmd.developer_uuid, | |
fullname: cmd.fullname, | |
email: cmd.email | |
}) | |
end | |
end | |
end | |
def with_developer(developer_uuid) | |
Developer.new.tap do |developer| | |
developer_version = @developer_store.load(developer, developer_uuid) | |
event = yield developer | |
@developer_store.store(event, developer_uuid, developer_version) | |
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
class Developer | |
HasBeenAlreadyRegistered = Class.new(StandardError) | |
EmailAddressNotUniq = Class.new(StandardError) | |
def initialize | |
@state = nil | |
end | |
def register | |
raise HasBeenAlreadyRegistered if @state == :registered | |
@state = :registered | |
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
class DeveloperStore | |
def load(developer, developer_uuid) | |
current_version = 0 | |
@event_store.read.stream(stream_name(developer_uuid)).forward.each do |event| | |
case event | |
when DeveloperRegistered | |
apply_developer_registered(developer, event) | |
end | |
current_version += 1 | |
end | |
current_version | |
end | |
def store(event, developer_uuid, developer_version) | |
@event_store.publish( | |
event, | |
stream_name: stream_name(developer_uuid), | |
expected_version: developer_version | |
) | |
end | |
private | |
def initialize(event_store:) | |
@event_store = event_store | |
end | |
def stream_name(developer_uuid) | |
"Developer$#{developer_uuid}" | |
end | |
def apply_developer_registered(developer, event) | |
developer.register(event.data[:fullname], event.data[:email]) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment