Class: FourthDimensional::RecordProjector

Inherits:
Object
  • Object
show all
Includes:
Eventable
Defined in:
lib/fourth_dimensional/record_projector.rb

Overview

FourthDimensional::RecordProjector

class PostProjector < FourthDimensional::RecordProjector
  self.record_class = 'Post'

  on TitleChanged do |event|
    record.title = event.title
  end
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Eventable

included

Constructor Details

#initialize(aggregate_id:) ⇒ RecordProjector

Returns a new instance of RecordProjector.



22
23
24
# File 'lib/fourth_dimensional/record_projector.rb', line 22

def initialize(aggregate_id:)
  @record = record_class.constantize.find_or_initialize_by(id: aggregate_id)
end

Instance Attribute Details

#recordObject (readonly)

The current instance of the projected record



20
21
22
# File 'lib/fourth_dimensional/record_projector.rb', line 20

def record
  @record
end

Class Method Details

.call(*events) ⇒ Object

Bulk apply and save events to multiple aggregates.



54
55
56
57
58
# File 'lib/fourth_dimensional/record_projector.rb', line 54

def self.call(*events)
  events.flatten.group_by(&:aggregate_id).each do |aggregate_id, events|
    new(aggregate_id: aggregate_id).call(events)
  end
end

Instance Method Details

#apply_event(event) ⇒ Object

Invokes the event binding.

post_projector.apply_event(TitleChanged.new(aggregate_id: aggregate_id,
                                            data: {title: 'new-post-title'}))


30
31
32
33
34
# File 'lib/fourth_dimensional/record_projector.rb', line 30

def apply_event(event)
  callback = self.class.event_bindings[event.class]
  return if callback.nil?
  instance_exec(event, &callback)
end

#call(*events) ⇒ Object

Applies multiple events and saves at the end.

projector.record.persisted? # => false
projector.call(event1, event2)
projector.record.persisted? # => true


48
49
50
51
# File 'lib/fourth_dimensional/record_projector.rb', line 48

def call(*events)
  events.flatten.map(&method(:apply_event))
  save
end

#saveObject

Saves the record at it’s current state.

post_projector.save


39
40
41
# File 'lib/fourth_dimensional/record_projector.rb', line 39

def save
  record.save
end