Module: Funes
- Defined in:
- lib/funes.rb,
lib/funes/engine.rb,
lib/funes/version.rb,
lib/funes/inspection.rb,
app/models/funes/event.rb,
lib/funes/associations.rb,
lib/funes/configuration.rb,
lib/funes/unknown_event.rb,
app/models/funes/event_entry.rb,
app/jobs/funes/application_job.rb,
app/projections/funes/projection.rb,
app/models/funes/application_record.rb,
app/event_streams/funes/event_stream.rb,
app/helpers/funes/application_helper.rb,
app/mailers/funes/application_mailer.rb,
app/jobs/funes/persist_projection_job.rb,
lib/generators/funes/install_generator.rb,
lib/funes/conflicting_actual_time_error.rb,
lib/funes/event_metainformation_builder.rb,
lib/funes/invalid_event_metainformation.rb,
lib/funes/invalid_materialization_state.rb,
lib/funes/unknown_materialization_model.rb,
app/helpers/funes/projection_test_helper.rb,
lib/generators/funes/initializer_generator.rb,
app/controllers/funes/application_controller.rb,
app/serializers/funes/event_stream_serializer.rb,
lib/funes/missing_actual_time_attribute_error.rb,
lib/generators/funes/materialization_table_generator.rb
Overview
Funes is an event sourcing framework for Ruby on Rails.
Instead of updating state in place, Funes stores immutable events as the source of truth, then derives current state by replaying them through projections. This provides complete audit trails, temporal queries, and the ability to create multiple read models from the same event stream.
Core Concepts
- Events (Event): Immutable facts representing something that happened
- Event Streams (EventStream): Append-only sequences of events for a specific entity
- Projections (Projection): Transform events into read models (state)
Getting Started
-
Install the gem and run migrations:
$ bin/rails generate funes:install $ bin/rails db:migrate -
Define your events:
class Order::Placed < Funes::Event attribute :total, :decimal attribute :customer_id, :string validates :total, presence: true end -
Define a projection:
class OrderProjection < Funes::Projection materialization_model OrderSnapshot interpretation_for Order::Placed do |state, event, _at| state.assign_attributes(total: event.total) state end end -
Create an event stream:
class OrderEventStream < Funes::EventStream add_transactional_projection OrderProjection end -
Append events:
stream = OrderEventStream.for("order-123") event = stream.append(Order::Placed.new(total: 99.99, customer_id: "cust-1"))
Three-Tier Consistency Model
Funes provides fine-grained control over projection execution:
- Consistency Projection: Validates business rules before persisting events
- Transactional Projections: Execute synchronously in the same database transaction
- Async Projections: Execute asynchronously via ActiveJob
Bitemporal History
Funes supports two independent temporal dimensions:
- Record history (
as_of/created_at): When the system learned about an event - Actual history (
at/occurred_at): When the event actually occurred in the real world
This enables queries like "what did the system know at time T?" (as_of) and
"what had actually happened by time T?" (at), as well as full bitemporal queries
combining both dimensions.
Defined Under Namespace
Modules: ApplicationHelper, Associations, Generators, Inspection, ProjectionTestHelper Classes: ApplicationController, ApplicationJob, ApplicationMailer, ApplicationRecord, Configuration, ConflictingActualTimeError, Engine, Event, EventEntry, EventMetainformation, EventMetainformationBuilder, EventStream, EventStreamSerializer, InvalidEventMetainformation, InvalidMaterializationState, MissingActualTimeAttributeError, PersistProjectionJob, Projection, UnknownEvent, UnknownMaterializationModel
Constant Summary collapse
- VERSION =
"0.3.0"
Class Method Summary collapse
Class Method Details
.configuration ⇒ Object
92 93 94 |
# File 'lib/funes.rb', line 92 def configuration @configuration ||= Configuration.new end |
.configure {|configuration| ... } ⇒ Object
96 97 98 |
# File 'lib/funes.rb', line 96 def configure yield(configuration) end |