This document discusses moving away from an ActiveRecord pattern to using events and CQRS architecture. It describes capturing all changes as a sequence of events stored in an event store. Events are raised by domain models and handled asynchronously. Reads and writes are separated, with denormalized data stored in a read database. This allows for simpler domain models focused on objects and events rather than data access. Code examples demonstrate raising domain events, handling commands, and updating read models from stored events.
10. 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
11. 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
12. 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
13. Active Record
A single model cannot be appropriate for
reporting, searching and transactional
behaviour.
Greg Young
14. Read vs Write
Reads and writes are two different concerns
Reads are simpler
Writes need logic
22. Thinking in events
Every change is an event.
add_item
1
add_item
2
remove_item
1
add_item
3
time
23. 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.
26. Pros
• Encapsulation
• Separation of concern
• Simple storage
• Performance/Scaling
• Simple testing
• More information granularity
• Easy integration with other services
27. Cons
• Complex for simple scenarios
• Cost of infrastructure
• Long-living objects needs time to be reconstructed
• Tools needed (i.e. rebuild the state)
43. 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)