Class: Funes::Projection
- Inherits:
-
Object
- Object
- Funes::Projection
- Defined in:
- app/projections/funes/projection.rb
Overview
Projections perform the necessary pattern-matching to compute and aggregate the interpretations that the system gives to a particular collection of events. A projection consists of a series of interpretations defined by the programmer and an aggregated representation of these interpretations (therefore, a representation of transient and final states) which is referenced as the *materialized representation*.
A projection can be virtual or persistent. In practical terms, what defines this characteristic is the type of *materialized representation* configured in the projection.
-
**Virtual projection:** has an ActiveModel instance as its materialized representation. An instance like this
is not persistent, but can be calculated at runtime and has characteristics like validation that are quite valuable in the context of a projection.
-
**Persistent projection:** has an ActiveRecord instance as its materialized representation. A persistent
projection has the same validation capabilities but can be persisted and serve the search patterns needed for the application (read model or even [eager read derivation](martinfowler.com/bliki/EagerReadDerivation.html)).
## Bitemporal Queries
Projections support two temporal dimensions:
-
**Record history** (‘as_of`): Determines which events are loaded from the database (by `created_at`). This is handled at the EventStream level before events reach the projection.
-
**Actual history** (‘at`): The temporal reference for the projection. Passed to all interpretation blocks as the third argument.
All interpretation blocks (‘initial_state`, `interpretation_for`, and `final_state`) receive `at` as their temporal reference, representing when events actually occurred rather than when the system recorded them.
Class Method Summary collapse
-
.final_state {|transient_state, at| ... } ⇒ void
Register a final interpretation of the state.
-
.initial_state {|materialization_model, at| ... } ⇒ void
Registers the initial transient state that will be used for the current projection’s interpretations.
-
.interpretation_for(event_type) {|state, event, at| ... } ⇒ void
Registers an interpretation block for a given event type.
-
.materialization_model(active_record_or_model) ⇒ void
Register the projection’s materialization model.
-
.raise_on_unknown_events ⇒ void
It changes the sensibility of the projection about events that it doesn’t know how to interpret.
Class Method Details
.final_state {|transient_state, at| ... } ⇒ void
This method returns an undefined value.
Register a final interpretation of the state.
*Default behavior:* when this is not defined the projection does nothing after the interpretations
102 103 104 105 |
# File 'app/projections/funes/projection.rb', line 102 def final_state(&block) @interpretations ||= {} @interpretations[:final] = block end |
.initial_state {|materialization_model, at| ... } ⇒ void
This method returns an undefined value.
Registers the initial transient state that will be used for the current projection’s interpretations.
*Default behavior:* When no block is provided the initial state defaults to a new instance of the configured materialization model.
81 82 83 84 |
# File 'app/projections/funes/projection.rb', line 81 def initial_state(&block) @interpretations ||= {} @interpretations[:init] = block end |
.interpretation_for(event_type) {|state, event, at| ... } ⇒ void
This method returns an undefined value.
Registers an interpretation block for a given event type.
Inside interpretation blocks, you can reject events by calling event.errors.add(…) on the event. When used as a **consistency projection**, these errors will be transferred to event.interpretation_errors and the event will not be persisted. In transactional or async projections, errors added to the event have no rejection effect and will be logged as a warning.
59 60 61 62 |
# File 'app/projections/funes/projection.rb', line 59 def interpretation_for(event_type, &block) @interpretations ||= {} @interpretations[event_type] = block end |
.materialization_model(active_record_or_model) ⇒ void
This method returns an undefined value.
Register the projection’s materialization model
121 122 123 |
# File 'app/projections/funes/projection.rb', line 121 def materialization_model(active_record_or_model) @materialization_model = active_record_or_model end |
.raise_on_unknown_events ⇒ void
This method returns an undefined value.
It changes the sensibility of the projection about events that it doesn’t know how to interpret
By default, a projection ignores events that it doesn’t have interpretations for. This method informs the projection that in cases like that an Funes::UnknownEvent should be raised and the DB transaction should be rolled back.
137 138 139 |
# File 'app/projections/funes/projection.rb', line 137 def raise_on_unknown_events @throws_on_unknown_events = true end |