SlideShare a Scribd company logo
1 of 22
Download to read offline
DDD, Rails and persistence
Michał Łomnicki
January, 2016
DRUG
1 / 21
Inspiration
Blog
https://vaughnvernon.co
Ideal DDD Aggregate Store
Book
2 / 21
Problem
I want DDD in my Rails project
I want fast and clean tests
I want to build my application around domain objects not around database schema
...but I struggle with persistence and ActiveRecord gets into my way all the time
3 / 21
Model
classSquad
includeVirtus.model#optional,canbePORO
MAX_FIRST_SQUAD_PLAYERS=11
attribute:id, UUID
attribute:match_id, UUID
attribute:team_id, UUID
attribute:formation, Formation
attribute:first_squad,Set[Player]
attribute:bench, Set[Player]
4 / 21
Model
defremove_from_first_squad(player)
raiseSquadErrorif!first_squad.member?(player)
first_squad.delete(player)
bench.add(player)
end
defadd_to_first_squad(player)
raiseSquadErrorif!bench.member?(player)
raiseSquadErroriffirst_squad.size==MAX_FIRST_SQUAD_PLAYERS
bench.remove(player)
first_squad.add(player)
end
5 / 21
Model
defsubstitute(player_off,player_on)
remove_from_first_squad(player_off)
add_to_first_squad(player_on)
DomainEventPublisher.publish(
PlayerSubstituted.new(
squad_id: id,
player_off_id:player_off.id,
player_on_id: player_on.id
)
)
end
6 / 21
Service
classSquadService
includeTransactionSupport
definitialize(squad_repository,player_repository)
@squad_repository =squad_repository
@player_repository=player_repository
end
defsubstitute(substitution_form)
transactiondo
DomainEventPublisher.subscribe(PlayerSubstituted,SomeHandler)
player_off=player_repository.find(substitution_form.player_off_id)
player_on =player_repository.find(substitution_form.player_on_id)
squad =squad_repository.find(substitution_form.squad_id)
squad.substitute(player_off,player_on)
squad_repository.save(squad)
end
end
defchange_formation(formation_form)
...
end
end
7 / 21
Repository
classSquadRepository
defsave(squad)
ifsquad.id
update(squad)
else
create(squad)
end
end
defcreate(squad)
SquadAR.create(
match_id:squad.match_id,
formation:squad.formation.to_s,
squad_players:
squad.first_squad.map{|player|PlayerAR.new(first_squad:true,...)}
+squad.bench.map{|player|PlayerAR.new(first_squad:false,...)}
)
end
...
8 / 21
Repository / Naive update
defupdate(squad)
record=SquadAR.find(squad.id)
record.formation=squad.formation.to_s
#deleteandre-createassociations
record.squad_players=
squad.first_squad.map{|player|PlayerAR.new(first_squad:true,...)}
+squad.bench.map{|player|PlayerAR.new(first_squad:false,...)}
record.save
end
9 / 21
Repository / Naive update
defupdate(squad)
record=SquadAR.find(squad.id)
record.formation=squad.formation.to_s
#deleteandre-createassociations
record.squad_players=
squad.first_squad.map{|player|PlayerAR.new(first_squad:true,...)}
+squad.bench.map{|player|PlayerAR.new(first_squad:false,...)}
record.save
end
Hard to maintain
Error­prone
Poor performance
10 / 21
Solution 1
Data Mapper
No mature Data Mapper for Ruby
ROM looks promising
...but is yet incomplete
11 / 21
Solution 2
Events as a storage mechanism
Yes, that's a good solution
Big mental model change
12 / 21
Solution 3
Postgres + JSON
Ideal DDD Aggregate store?
Aggregate data stored as JSON
One database row ­ one aggregate
create_table"squads"do|t|
t.jsonb:data,null:false
end
13 / 21
DB schema
create_table"users"do|t|
t.jsonb:data,null:false
end
create_table"matches"do|t|
t.jsonb:data,null:false
end
create_table"teams"do|t|
t.jsonb:data,null:false
end
create_table"squads"do|t|
t.jsonb:data,null:false
end
14 / 21
JSON Repository
classSquadRepository
defsave(squad)
ifsquad.id
update(squad)
else
create(squad)
end
end
deffind(squad_id)
Domain::Squad.new(SquadAR.find(squad_id))
end
private
defcreate(squad)
SquadAR.create(data:squad.as_json)
end
defupdate(squad)
SquadAR.where(id:squad.id).update_all(data:squad.as_json)
end
end
15 / 21
Why not Mongo? This looks like NoSQL
Mongo is not ACID­compliant
Transactions only at the document level
16 / 21
Postgres + JSON
JSON introduced in Postgres 9.3
JSONB introduced in Postgres 9.4
JSONB can be indexed
Postgres = ACID
No foreign keys and unique indexes
Data consistency ensured at application level
Introduce this approach in the existing database
17 / 21
Postgres + JSON
JSON introduced in Postgres 9.3
JSONB introduced in Postgres 9.4
JSONB can be indexed
Postgres = ACID
No foreign keys and unique indexes
Data consistency ensured at application level
Introduce this approach in the existing database
CREATEINDEXONsquadsUSINGgin(data)
SELECT*FROMsquadsWHERE(data->>'match_id')::INT=12
18 / 21
Locking
Some locking mechanism is required
Optimisic locking is preferred
a)Process1reads
b)Process2reads
c)Process1writes
d)Process2overwritesc)
SquadAR.where(id:squad.id,lock_version:current_version[squad]).update_all(
data: squad.as_json,
lock_version:current_version[squad]+1
)
19 / 21
Lessons learnt
It works
Changes are easy to introduce
Fast and easy to store and load an entire aggregate
Code explains the application, not the DB schema
Migrations require more work
Most probably you will build a read model
De­normalized data needs synchronization
Avoid big aggregates
No help from the database (foreign keys, not null, etc)
Can't really fiddle in railsconsole
Squad.find(123).squad_players.update_all(...)
20 / 21
Thank you
Resources:
https://vaughnvernon.co/?p=942
http://www.amazon.com/Implementing­Domain­Driven­Design­Vaughn­
Vernon/dp/0321834577
http://www.postgresql.org/docs/9.4/static/datatype­json.html
21 / 21
DDD, Rails and persistence

More Related Content

Similar to DDD, Rails and persistence

Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-senseBen Lin
 
Kharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backendKharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backendMax Klymyshyn
 
The new static resources framework
The new static resources frameworkThe new static resources framework
The new static resources frameworkmarcplmer
 
Modules and EmbedJS
Modules and EmbedJSModules and EmbedJS
Modules and EmbedJSJens Arps
 
Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Matt Raible
 
SeedStack feature tour
SeedStack feature tourSeedStack feature tour
SeedStack feature tourSeedStack
 
Introduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceIntroduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceBo-Yi Wu
 
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Codemotion
 
Drupal tips 'n tricks
Drupal tips 'n tricksDrupal tips 'n tricks
Drupal tips 'n tricksJohn Tsevdos
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersNaresha K
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Joao Lucas Santana
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJoaquim Rocha
 
Application Security from the Inside - OWASP
Application Security from the Inside - OWASPApplication Security from the Inside - OWASP
Application Security from the Inside - OWASPSqreen
 
Display Suite: A Themers Perspective
Display Suite: A Themers PerspectiveDisplay Suite: A Themers Perspective
Display Suite: A Themers PerspectiveMediacurrent
 
Introduction to bdd
Introduction to bddIntroduction to bdd
Introduction to bddantannatna
 

Similar to DDD, Rails and persistence (20)

Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-sense
 
Kharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backendKharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backend
 
The new static resources framework
The new static resources frameworkThe new static resources framework
The new static resources framework
 
Modules and EmbedJS
Modules and EmbedJSModules and EmbedJS
Modules and EmbedJS
 
Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020
 
lecture5
lecture5lecture5
lecture5
 
lecture5
lecture5lecture5
lecture5
 
WP plugin - Lazar Dačić
WP plugin - Lazar DačićWP plugin - Lazar Dačić
WP plugin - Lazar Dačić
 
micro-frontends-with-vuejs
micro-frontends-with-vuejsmicro-frontends-with-vuejs
micro-frontends-with-vuejs
 
SeedStack feature tour
SeedStack feature tourSeedStack feature tour
SeedStack feature tour
 
Introduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceIntroduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript Conference
 
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
 
Drupal tips 'n tricks
Drupal tips 'n tricksDrupal tips 'n tricks
Drupal tips 'n tricks
 
Browserify
BrowserifyBrowserify
Browserify
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Application Security from the Inside - OWASP
Application Security from the Inside - OWASPApplication Security from the Inside - OWASP
Application Security from the Inside - OWASP
 
Display Suite: A Themers Perspective
Display Suite: A Themers PerspectiveDisplay Suite: A Themers Perspective
Display Suite: A Themers Perspective
 
Introduction to bdd
Introduction to bddIntroduction to bdd
Introduction to bdd
 

More from Michał Łomnicki

More from Michał Łomnicki (7)

Forget Ruby. Forget CoffeeScript. Do SOA
Forget Ruby. Forget CoffeeScript. Do SOAForget Ruby. Forget CoffeeScript. Do SOA
Forget Ruby. Forget CoffeeScript. Do SOA
 
Having fun with legacy apps
Having fun with legacy appsHaving fun with legacy apps
Having fun with legacy apps
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Schema plus
Schema plusSchema plus
Schema plus
 
Nodejs + Rails
Nodejs + RailsNodejs + Rails
Nodejs + Rails
 
ACID - Transakcje
ACID - TransakcjeACID - Transakcje
ACID - Transakcje
 
Cap Theorem
Cap TheoremCap Theorem
Cap Theorem
 

Recently uploaded

Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 

Recently uploaded (20)

Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 

DDD, Rails and persistence