class RailsEventSourcing::BaseEvent
This is the BaseEvent
class that all Events inherit from. It takes care of serializing ‘data` and `metadata` via json It defines setters and accessors for the defined `data_attributes` After create, it calls `apply` to apply changes.
Public Class Methods
# File lib/rails-event-sourcing/base_event.rb, line 73 def aggregate_name inferred_aggregate = reflect_on_all_associations(:belongs_to).first raise "Events must belong to an aggregate" if inferred_aggregate.nil? inferred_aggregate.name end
Define attributes to be serialize in the ‘data` column. It generates setters and getters for those.
Example:
class MyEvent < RailsEventSourcing::BaseEvent
data_attributes :title, :description, :drop_id
end
# File lib/rails-event-sourcing/base_event.rb, line 88 def data_attributes(*attrs) @data_attributes ||= [] attrs.map(&:to_s).each do |attr| @data_attributes << attr unless @data_attributes.include?(attr) define_method attr do self.data ||= {} self.data[attr] end define_method "#{attr}=" do |arg| self.data ||= {} self.data[attr] = arg end end @data_attributes end
Underscored class name by default. ex: “post/updated” Used when sending events to the data pipeline
# File lib/rails-event-sourcing/base_event.rb, line 110 def event_name name.underscore end
# File lib/rails-event-sourcing/base_event.rb, line 114 def events_for(aggregate) where(aggregate_name => aggregate) end
# File lib/rails-event-sourcing/base_event.rb, line 118 def reserved_column_names %w[id created_at updated_at] end
Public Instance Methods
# File lib/rails-event-sourcing/base_event.rb, line 25 def aggregate public_send aggregate_name end
# File lib/rails-event-sourcing/base_event.rb, line 29 def aggregate=(model) public_send "#{aggregate_name}=", model end
# File lib/rails-event-sourcing/base_event.rb, line 43 def aggregate_id public_send "#{aggregate_name}_id" end
# File lib/rails-event-sourcing/base_event.rb, line 33 def aggregate_id=(id) public_send "#{aggregate_name}_id=", id end
Apply the event to the aggregate passed in. Must return the aggregate.
# File lib/rails-event-sourcing/base_event.rb, line 39 def apply(aggregate) raise NotImplementedError end
# File lib/rails-event-sourcing/base_event.rb, line 47 def build_aggregate public_send "build_#{aggregate_name}" end
Rollback an aggregate entity to a specific version
Update the aggregate with the changes up to the current event and destroys the events after
# File lib/rails-event-sourcing/base_event.rb, line 55 def rollback! base_class = self.class.superclass == RailsEventSourcing::BaseEvent ? self.class : self.class.superclass new_attributes = aggregate.class.new.attributes preserve_columns = new_attributes.keys - base_class.reserved_column_names new_attributes.slice!(*preserve_columns) aggregate.assign_attributes(new_attributes) aggregate.transaction do base_class.events_for(aggregate).where('id > ?', id).destroy_all base_class.events_for(aggregate).reorder('id ASC').each do |event| event.apply(aggregate) end aggregate.save! end end
Private Instance Methods
Apply the transformation to the aggregate and save it
# File lib/rails-event-sourcing/base_event.rb, line 131 def apply_and_persist aggregate.lock! if aggregate.persisted? self.aggregate = apply(aggregate) aggregate.save! self.aggregate_id = aggregate.id if aggregate_id.nil? end
# File lib/rails-event-sourcing/base_event.rb, line 138 def dispatch Dispatcher.dispatch(self) end
Build aggregate when the event is creating an aggregate
# File lib/rails-event-sourcing/base_event.rb, line 126 def preset_aggregate self.aggregate ||= build_aggregate end