# Rails Event Store [Rails Event Store (RES)](https://railseventstore.org/) is a library for publishing, consuming, storing and retrieving events. It's your best companion for going with an event-driven architecture for your Rails application. You can use it: * as your [Publish-Subscribe bus](https://railseventstore.org/docs/pubsub/) * to decouple core business logic from external concerns in Hexagonal style architectures * as [an alternative to ActiveRecord callbacks and Observers](https://blog.arkency.com/2016/05/domain-events-over-active-record-callbacks/) * as a communication layer between loosely coupled components * to react to published events synchronously or asynchronously * to extract side-effects (notifications, metrics etc) from your controllers and services into event handlers * to build an audit-log * to create read-models * to implement event-sourcing ## Documentation Documentation, tutorials and code samples are available at [https://railseventstore.org](https://railseventstore.org). ## Code status This single repository hosts several gems and website with documentation — see the [contribution guide](https://railseventstore.org/contributing/). We're aiming for 100% mutation coverage in this project. This is why: - [Why I want to introduce mutation testing to the rails_event_store gem](https://blog.arkency.com/2015/04/why-i-want-to-introduce-mutation-testing-to-the-rails-event-store-gem/) - [Mutation testing and continuous integration](https://blog.arkency.com/2015/05/mutation-testing-and-continuous-integration/) Whenever you fix a bug or add a new feature, we require that the coverage doesn't go down. ### RailsEventStore gems | Name | CI | Version | Downloads | |--------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| | [rails_event_store](/rails_event_store) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/rails_event_store_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/rails_event_store_test.yml) | [![Gem](https://img.shields.io/gem/v/rails_event_store?style=flat-square)](https://rubygems.org/gems/rails_event_store) | [![Gem](https://img.shields.io/gem/dt/rails_event_store?style=flat-square)](https://rubygems.org/gems/rails_event_store) | | [ruby_event_store-active_record](/ruby_event_store/active_record) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-active_record_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-active_record_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-active_record?style=flat-square)](https://rubygems.org/gems/ruby_event_store-active_record) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-active_record?style=flat-square)](https://rubygems.org/gems/ruby_event_store-active_record) | | [ruby_event_store](/ruby_event_store) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store?style=flat-square)](https://rubygems.org/gems/ruby_event_store) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store?style=flat-square)](https://rubygems.org/gems/ruby_event_store) | | [ruby_event_store-browser](/ruby_event_store-browser) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-browser_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-browser_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-browser?style=flat-square)](https://rubygems.org/gems/ruby_event_store-browser) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-browser?style=flat-square)](https://rubygems.org/gems/ruby_event_store-browser) | | [ruby_event_store-rspec](/ruby_event_store-rspec) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-rspec_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-rspec_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-rspec?style=flat-square)](https://rubygems.org/gems/ruby_event_store-rspec) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-rspec?style=flat-square)](https://rubygems.org/gems/ruby_event_store-rspec) | | [aggregate_root](/aggregate_root) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/aggregate_root_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/aggregate_root_test.yml) | [![Gem](https://img.shields.io/gem/v/aggregate_root?style=flat-square)](https://rubygems.org/gems/aggregate_root) | [![Gem](https://img.shields.io/gem/dt/aggregate_root?style=flat-square)](https://rubygems.org/gems/aggregate_root) | ### Contributed gems | Name | CI | Version | Downloads | |-----------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| | [ruby_event_store-outbox](/contrib/ruby_event_store-outbox) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-outbox_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-outbox_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-outbox?style=flat-square)](https://rubygems.org/gems/ruby_event_store-outbox) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-outbox?style=flat-square)](https://rubygems.org/gems/ruby_event_store-outbox) | | [ruby_event_store-protobuf](/contrib/ruby_event_store-protobuf) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-protobuf_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-protobuf_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-protobuf?style=flat-square)](https://rubygems.org/gems/ruby_event_store-protobuf) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-protobuf?style=flat-square)](https://rubygems.org/gems/ruby_event_store-protobuf) | | [ruby_event_store-profiler](/contrib/ruby_event_store-profiler) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-profiler_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-profiler_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-profiler?style=flat-square)](https://rubygems.org/gems/ruby_event_store-profiler) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-profiler?style=flat-square)](https://rubygems.org/gems/ruby_event_store-profiler) | | [ruby_event_store-flipper](/contrib/ruby_event_store-flipper) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-flipper_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-flipper_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-flipper?style=flat-square)](https://rubygems.org/gems/ruby_event_store-flipper) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-flipper?style=flat-square)](https://rubygems.org/gems/ruby_event_store-flipper) | | [ruby_event_store-transformations](/contrib/ruby_event_store-transformations) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-transformations_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-transformations_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-transformations?style=flat-square)](https://rubygems.org/gems/ruby_event_store-transformations) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-transformations?style=flat-square)](https://rubygems.org/gems/ruby_event_store-transformations) | | [ruby_event_store-rom](/contrib/ruby_event_store-rom) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-rom_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-rom_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-rom?style=flat-square)](https://rubygems.org/gems/ruby_event_store-rom) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-rom?style=flat-square)](https://rubygems.org/gems/ruby_event_store-rom) | | [ruby_event_store-sidekiq_scheduler](/contrib/ruby_event_store-sidekiq_scheduler) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-sidekiq_scheduler_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-sidekiq_scheduler_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-sidekiq_scheduler?style=flat-square)](https://rubygems.org/gems/ruby_event_store-sidekiq_scheduler) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-sidekiq_scheduler?style=flat-square)](https://rubygems.org/gems/ruby_event_store-sidekiq_scheduler) | | [ruby_event_store-cli](/contrib/ruby_event_store-cli) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-cli_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-cli_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-cli?style=flat-square)](https://rubygems.org/gems/ruby_event_store-cli) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-cli?style=flat-square)](https://rubygems.org/gems/ruby_event_store-cli) | | [ruby_event_store-mcp](/contrib/ruby_event_store-mcp) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-mcp_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-mcp_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-mcp?style=flat-square)](https://rubygems.org/gems/ruby_event_store-mcp) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-mcp?style=flat-square)](https://rubygems.org/gems/ruby_event_store-mcp) | | [ruby_event_store-process_manager](/contrib/ruby_event_store-process_manager) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-process_manager_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-process_manager_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-process_manager?style=flat-square)](https://rubygems.org/gems/ruby_event_store-process_manager) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-process_manager?style=flat-square)](https://rubygems.org/gems/ruby_event_store-process_manager) | | [ruby_event_store-sequel](/contrib/ruby_event_store-sequel) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-sequel_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-sequel_test.yml) | [![Gem](https://img.shields.io/gem/v/ruby_event_store-sequel?style=flat-square)](https://rubygems.org/gems/ruby_event_store-sequel) | [![Gem](https://img.shields.io/gem/dt/ruby_event_store-sequel?style=flat-square)](https://rubygems.org/gems/ruby_event_store-sequel) | ### Unreleased contributed gems | Name | CI | |-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [ruby_event_store-newrelic](/contrib/ruby_event_store-newrelic) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/ruby_event_store-newrelic_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/ruby_event_store-newrelic_test.yml) | | [minitest-ruby_event_store](/contrib/minitest-ruby_event_store) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/minitest-ruby_event_store_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/minitest-ruby_event_store_test.yml) | | [dres_rails](/contrib/distributed_rails_event_store/dres_rails) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/dres_rails_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/dres_rails_test.yml) | | [dres_client](/contrib/distributed_rails_event_store/dres_client) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/RailsEventStore/rails_event_store/dres_client_test.yml?style=flat-square)](https://github.com/RailsEventStore/rails_event_store/actions/workflows/dres_client_test.yml) | ## About Arkency This repository is funded and maintained by [arkency](https://arkency.com). Make sure to check out our [Rails Architect Masterclass training](https://arkademy.dev) and long-term [support plans](https://railseventstore.org/support/) available.