Class: Lyra::Aggregate

Inherits:
Object
  • Object
show all
Defined in:
lib/lyra/aggregate.rb

Overview

Base aggregate class for event sourcing

Direct Known Subclasses

GenericAggregate

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id = nil) ⇒ Aggregate

Returns a new instance of Aggregate.



6
7
8
9
10
11
# File 'lib/lyra/aggregate.rb', line 6

def initialize(id = nil)
  @id = id
  @version = 0
  @changes = []
  @state = {}
end

Instance Attribute Details

#changes ⇒ Object (readonly)

Returns the value of attribute changes.



4
5
6
# File 'lib/lyra/aggregate.rb', line 4

def changes
  @changes
end

#id ⇒ Object (readonly)

Returns the value of attribute id.



4
5
6
# File 'lib/lyra/aggregate.rb', line 4

def id
  @id
end

#version ⇒ Object (readonly)

Returns the value of attribute version.



4
5
6
# File 'lib/lyra/aggregate.rb', line 4

def version
  @version
end

Class Method Details

.load(id, event_store = nil) ⇒ Object

Load aggregate from event stream



14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/lyra/aggregate.rb', line 14

def self.load(id, event_store = nil)
  event_store ||= Lyra.config.event_store
  aggregate = new(id)

  stream_name = aggregate.stream_name
  events = event_store.read.stream(stream_name).to_a

  events.each { |event| aggregate.apply(event, persisted: true) }
  aggregate
rescue RailsEventStore::EventNotFound
  new(id)
end

Instance Method Details

#apply(event, persisted: false) ⇒ Object

Apply an event to the aggregate



28
29
30
31
32
33
34
35
36
# File 'lib/lyra/aggregate.rb', line 28

def apply(event, persisted: false)
  method_name = "apply_#{event.class.name.demodulize.underscore}"

  if respond_to?(method_name, true)
    send(method_name, event)
    @version += 1 if persisted
    @changes << event unless persisted
  end
end

#store(event_store = nil) ⇒ Object

Store pending changes to event store



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/lyra/aggregate.rb', line 39

def store(event_store = nil)
  return if @changes.empty?

  event_store ||= Lyra.config.event_store

  @changes.each do |event|
    event_store.publish(event, stream_name: stream_name)
  end

  @changes.clear
end

#stream_name ⇒ Object



51
52
53
# File 'lib/lyra/aggregate.rb', line 51

def stream_name
  "#{self.class.name.demodulize}$#{id}"
end