SlideShare a Scribd company logo
From ActiveRecord to
Events
Emanuele DelBono
@emadb
From ActiveRecord to EventSourcing
Customer
Address
Invoice
Items
Contacts
Role
Contract
Price
City
From ActiveRecord to EventSourcing
From ActiveRecord to EventSourcing
@emadb
I’m a software developer based
in Italy. I develop my apps in C#,
Javascript and some Ruby.
I’m a wannabe Ruby dev.
Lasagna architecture
View
Controller
Model (AR)
Database
O/RM
Active record
“An object that wraps a row in a database table or
view, encapsulates the database access, and adds
domain logic on that data.”
M. Fowler
Active record
1 table => 1 class
Too coupled with the database structure
No SRP
Database first
class User < ActiveRecord::Base
attr_accessible :email, :password
belongs_to :group
end
Get vs Post
def index
@products = Product.all
end
!
def create
@product = Product.new(product_params)
if @product.save
redirect_to @product
else
render action: 'new'
end
end
Active Record
A single model cannot be appropriate for
reporting, searching and transactional
behaviour.
Greg Young
Read vs Write
Reads and writes are two different concerns
Reads are simpler
Writes need logic
From ActiveRecord to EventSourcing
KEEP CALM
AND
STOP THINKING
IN CRUD
Command
Query
Responsibility
Segregation
CQRS
Presentation Layer
Handler
BL Repository
Write DB Read DB
Query Service
Denormalizer
CQRS
Fully normalized
Reads are easy
Writes became easier
SELECT fields FROM table (WHERE …)
Object state
id basket_id article_id quantity
1 4 8 1
2 3 8 3
3 3 6 1
4 4 5 1
From ActiveRecord to EventSourcing
Thinking in events
Every change is an event.
add_item
1
add_item
2
remove_item
1
add_item
3
time
Event Sourcing
Capture all changes to an application state as a
sequence of events.
M.Fowler
If the changes are stored in a database, we can rebuild the
state re-applying the events.
From ActiveRecord to EventSourcing
Event Sourcing
Presentation Layer
Bus
Handler
DMRepository
Event store Denormalizer
Query service
Read DB
Command
Events
Pros
• Encapsulation
• Separation of concern
• Simple storage
• Performance/Scaling
• Simple testing
• More information granularity
• Easy integration with other services
Cons
• Complex for simple scenarios
• Cost of infrastructure
• Long-living objects needs time to be reconstructed
• Tools needed (i.e. rebuild the state)
http://antwonlee.com/
Ingredients
• Rails app (no ActiveRecord)
• Redis (pub-sub)
• Sequel for querying data
• MongoDb (event store)
• Sqlite (Read db)
• Wisper (domain events)
Domain Model
Basket
BasketItem
Article
*
1
• Fully encapsulated (no accessors)
• Fully OOP
• Events for communication
• PORO
show_me_the_code.rb
include CommandExecutor
!
def add_to_basket
send_command AddToBasketCommand.new(
{"basket_id" => 42, "article_id" => params[:id].to_i})
redirect_to products_url
end
Controller
Bus
Command
POST /Products
add_to_basket
module CommandExecutor
!
def send_command (command)
class_name = command.class.name
channel = class_name.sub(/Command/, '')
@redis.publish channel, command.to_json
end
!
end
send_command
def consume(data)
basket = repository.get_basket(data["basket_id"])
article = repository.get_article(data["article_id"])
basket.add_item article
!
basket.commit
end
Bus
Handler
Command
handler
class Basket
include AggregateRootHelper
!
def add_item (item)
raise_event :item_added, {
basket_id: id,
item_code: item.code,
item_price: item.price
}
end
# ...
!
end
add_item
def raise_event(event, args)
@uncommited_events << {name: event, args: args}
send "on_#{event}", args
end
raise_event
DM (Basket)
Events
def get_item (item_code)
@items.select{|i| i.item_code == item_code}.try :first
end
!
def on_item_added (item)
get_item(item[:item_code]).try(:increase_quantity) ||
@items << BasketItem.new(item)
end
on_item_added
DM (Basket)
Events
def commit
while event = uncommited_events.shift
events_repository.store(id, event)
send_event event
end
end
commit
DM (Basket)
Event store
Event Store
def item_added(data)
db = Sequel.sqlite(AppSettings.sql_connection)
article = db[:products_view].where(code:
data[:item_code]).first
basket = db[:basket_view].where('basket_id = ? AND
article_id = ?', data[:basket_id], article[:id].to_i).first
if basket.nil?
#insert
else
db[:basket_view].where(id:
basket[:id]).update(quantity: (basket[:quantity] + 1))
end
end
denormalizer
Denormalizer
Read-Db
def index
@products=db[:basket_view]
end
Controller
Read DB
Query
GET /Products
index
Conclusion
• Stop thinking in CRUD
• Read and Write are different
• Domain model should be based on PORO
• CQRS/ES is useful in complex scenario
• Ruby power helps a lot (less infrastructure code)
https://github.com/emadb/revents

More Related Content

PPTX
Solid principles
PPT
SOLID Design Principles
PDF
Node.js - #1 - Introdução - Rodrigo Branas
PDF
Lecture 8 Enterprise Java Beans (EJB)
PDF
Microservices: Improving the autonomy of our teams with Event-Driven Architec...
PDF
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
PPT
Java Persistence API (JPA) Step By Step
PDF
From framework coupled code to #microservices through #DDD /by @codelytv
Solid principles
SOLID Design Principles
Node.js - #1 - Introdução - Rodrigo Branas
Lecture 8 Enterprise Java Beans (EJB)
Microservices: Improving the autonomy of our teams with Event-Driven Architec...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Java Persistence API (JPA) Step By Step
From framework coupled code to #microservices through #DDD /by @codelytv

What's hot (20)

PPTX
SOLID principles
PPTX
Php oop presentation
PPTX
jQuery
PDF
Solid Principles
PDF
JPA and Hibernate
PPTX
Introduction to microservices
PDF
React new features and intro to Hooks
PPTX
android sqlite
PDF
SOLID Design Principles applied in Java
PPTX
Introduction to microservices
PPT
Introduction to Javascript
PPTX
Microservices
PPTX
Hexagonal Design in Django
PPTX
Clean code: SOLID
PDF
The Beginner’s Guide To Spring Cloud
PDF
Introduction to web programming with JavaScript
PPSX
JSON in Oracle 18c and 19c
PDF
Javascript essentials
PPTX
Introduction to Spring Boot
PPTX
Entity Framework Core
SOLID principles
Php oop presentation
jQuery
Solid Principles
JPA and Hibernate
Introduction to microservices
React new features and intro to Hooks
android sqlite
SOLID Design Principles applied in Java
Introduction to microservices
Introduction to Javascript
Microservices
Hexagonal Design in Django
Clean code: SOLID
The Beginner’s Guide To Spring Cloud
Introduction to web programming with JavaScript
JSON in Oracle 18c and 19c
Javascript essentials
Introduction to Spring Boot
Entity Framework Core
Ad

Similar to From ActiveRecord to EventSourcing (20)

PPTX
12 Introduction to Rails
KEY
Modern Webdevelopment With Ruby On Rails
ODP
RailswayCon 2010 - Command Your Domain
PDF
RubyOnRails-Cheatsheet-BlaineKendall
PDF
RubyOnRails-Cheatsheet-BlaineKendall
PPT
Ruby on rails
PDF
Ruby On Rails
PDF
td_mxc_rubyrails_shin
PDF
td_mxc_rubyrails_shin
PPTX
Intro to Domain Driven Design
PDF
Beyond rails new
PPT
Ruby on Rails: Building Web Applications Is Fun Again!
PPT
Ruby On Rails
DOC
Rails interview questions
PPT
Active Record Data Modeling
PDF
Introduction to Domain-Driven Design in Ruby on Rails
PPT
Ruby On Rails
PDF
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...
PDF
DDD-rail Your Monorail
PPTX
Domain Driven Design Ruby Ways - JURNAL 05/10/2017
12 Introduction to Rails
Modern Webdevelopment With Ruby On Rails
RailswayCon 2010 - Command Your Domain
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
Ruby on rails
Ruby On Rails
td_mxc_rubyrails_shin
td_mxc_rubyrails_shin
Intro to Domain Driven Design
Beyond rails new
Ruby on Rails: Building Web Applications Is Fun Again!
Ruby On Rails
Rails interview questions
Active Record Data Modeling
Introduction to Domain-Driven Design in Ruby on Rails
Ruby On Rails
Software Design Trilogy Part III - Domain Driven Design for Ruby on Rails App...
DDD-rail Your Monorail
Domain Driven Design Ruby Ways - JURNAL 05/10/2017
Ad

More from Emanuele DelBono (13)

PDF
The simplest thing that could possibly work
PDF
Una crescita armoniosa
PDF
A sip of Elixir
PDF
React.js in real world apps.
PDF
An introduction to React.js
PDF
Ruby seen by a C# developer
PDF
Ruby loves DDD
PDF
An introduction to knockout.js
PDF
Node azure
PDF
Da programmatore a CEO
KEY
Sinatra for REST services
PPTX
Test driving an MVVM App
PPTX
The simplest thing that could possibly work
Una crescita armoniosa
A sip of Elixir
React.js in real world apps.
An introduction to React.js
Ruby seen by a C# developer
Ruby loves DDD
An introduction to knockout.js
Node azure
Da programmatore a CEO
Sinatra for REST services
Test driving an MVVM App

Recently uploaded (20)

PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
cuic standard and advanced reporting.pdf
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Encapsulation theory and applications.pdf
PDF
Electronic commerce courselecture one. Pdf
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
Cloud computing and distributed systems.
PDF
Modernizing your data center with Dell and AMD
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Machine learning based COVID-19 study performance prediction
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Chapter 3 Spatial Domain Image Processing.pdf
cuic standard and advanced reporting.pdf
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Unlocking AI with Model Context Protocol (MCP)
Building Integrated photovoltaic BIPV_UPV.pdf
Encapsulation theory and applications.pdf
Electronic commerce courselecture one. Pdf
NewMind AI Monthly Chronicles - July 2025
Mobile App Security Testing_ A Comprehensive Guide.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Dropbox Q2 2025 Financial Results & Investor Presentation
The AUB Centre for AI in Media Proposal.docx
Cloud computing and distributed systems.
Modernizing your data center with Dell and AMD
Digital-Transformation-Roadmap-for-Companies.pptx

From ActiveRecord to EventSourcing