SlideShare a Scribd company logo
SerializingValue
Objects in Rails
AraHacopian
@ahacop
SmartLogic
© 2015
Fat
Models
“[An] argument against Active Record is the fact that
it couples the object design to the database design.
This makes it more difficult to refactor either
design...”
“[An] argument against Active Record is the fact that
it couples the object design to the database design.
This makes it more difficult to refactor either
design...”
-- Martin Fowler, "Patterns of Enterprise Application
Architecture", inventor of the Active Record pattern
Single
Responsibility
Principle
Single ResponsibilityPrinciple
There should never be more than one reason for a
class to change
Single ResponsibilityPrinciple
Not: All the methods that do something with a person
go into the Person model
class Person < ActiveRecord::Base
def initials
first_name.chr + middle_name.chr + last_name.chr
end
def armenian?
if last_name.end_with?('ian')
'probably'
else
'probably not'
end
end
def weight_in_pounds
weight
end
def weight_in_kilograms
(weight * 0.453592).round
end
def weight_in_stone
(weight * 0.07142).round
end
end
Cohesion
"Where shouldthis method go?"
class Person < ActiveRecord::Base
def initials
first_name.chr + middle_name.chr + last_name.chr
end
def armenian?
if last_name.end_with?('ian')
'probably'
else
'probably not'
end
end
def weight_in_pounds
weight
end
def weight_in_kilograms
(weight * 0.453592).round
end
def weight_in_stone
(weight * 0.07142).round
end
end
has_one?
class Person < ActiveRecord::Base
has_one :weight
end
class Weight < ActiveRecord::Base
belongs_to :person
end
Value Objects
» A small object that represents a simple value
whose equality is based on its values rather than
its identity
» Immutable
» Examples: addresses, money, names.
Identityequalityin Ruby
> a = Object.new
> b = Object.new
> a.object_id
=> 70288883508240
> b.object_id
=> 70288892808780
> a == b
=> false
IdentityequalityinActiveRecord
> george_foreman = Person.create
> george_foreman.id
=> 1
> ara = Person.create
> ara.id
=> 2
> ara == george_foreman
=> false
IdentityequalityinActiveRecord
> george_foreman2 = Person.find(george_foreman.id)
> george_foreman2.id
=> 1
> george_foreman2 == george_foreman
=> true
IdentityequalityinActiveRecord
> george_foreman.object_id
=> 70288888679260
> george_foreman2.object_id
=> 70288855436880
> george_foreman.object_id == george_foreman2.object_id
=> false
IdentityequalityinActiveRecord
> george_foreman_jr = george_foreman.dup
> george_foreman_jr.id
=> nil
> george_foreman_jr == george_foreman
=> false
IdentityequalityinActiveRecord
> george_foreman_iii = george_foreman.clone
> george_foreman_iii.id
=> 1
> george_foreman_iii == george_foreman
=> true
IdentityequalityinActiveRecord
def ==(comparison_object)
super ||
comparison_object.instance_of?(self.class) &&
!id.nil? &&
comparison_object.id == id
end
alias :eql? :==
ExtractWeightfrom Person
class Weight
attr_reader :pounds
def initialize(pounds)
@pounds = pounds
end
def kilograms
(pounds * 0.453592).round
end
def stone
(pounds * 0.07142).round
end
end
Weightequality
> buck_fifty = Weight.new(150)
> buck_fifty.pounds
=> 150
> buck_fifty.object_id
=> 70288888679260
> buck_fifty2 = Weight.new(150)
> buck_fifty2.pounds
=> 150
> buck_fifty2.object_id
=> 70288855436880
Weightequality
> buck_fifty.pounds == buck_fifty2.pounds
=> true
> buck_fifty.object_id == buck_fifty2.object_id
=> false
> buck_fifty == buck_fifty2
=> false
Weightequality
> weights = [Weight.new(150), Weight.new(150), Weight.new(150)]
> weights.uniq.length
=> 3
> pounds_values = [150, 150, 150]
> pounds_values.uniq.length
=> 1
Weightasavalue object
class Weight
include Comparable
def <=>(other)
other.instance_of?(self.class) && pounds <=> other.pounds
end
def eql?(other)
self == other
end
def hash
@hash ||= pounds.hash
end
end
Value equalityforWeight
> buck_fifty = Weight.new(150)
> buck_fifty2 = Weight.new(150)
> buck_fifty.object_id == buck_fifty2.object_id
=> false
> buck_fifty == buck_fifty2
=> true
Value equalityforWeight
> weights = [Weight.new(150), Weight.new(150), Weight.new(150)]
> weights.uniq.length
=> 1
Nameasavalue object
class Name
attr_reader :title, :first, :middle, :last, :suffix
def initialize(title, first, middle, last, suffix)
@title, @first, @middle, @last, @suffix = title, first, middle, last, suffix
end
def initials
first.chr + middle.chr + last.chr
end
def armenian?
if last.end_with?('ian')
'probably'
else
'probably not'
end
end
Nameasavalue object
def ==(other)
other.instance_of?(self.class) &&
title == other.title &&
first == other.first &&
middle == other.middle &&
last == other.last &&
suffix == other.suffix
end
alias :eql? :==
def hash
@hash ||= title.hash ^ first.hash ^ middle.hash ^ last.hash ^ suffix.hash
end
end
3Waysto SerializeValue Objects
1.Serialize
2.Virtual Attributes
3.Composed_of
Serialize
class Person < ActiveRecord::Base
serialize :weight, Weight
end
class Weight
class << self
def dump(weight)
weight.pounds
end
def load(pounds)
new(pounds)
end
end
def initialize(pounds)
@pounds = pounds
end
attr_reader :pounds
def kilograms
(pounds * 0.453592).round
end
def stone
(pounds * 0.07142).round
end
end
class Weight
include Comparable
attr_reader :pounds
class << self
def dump(weight)
weight.pounds
end
def load(pounds)
new(pounds)
end
end
def initialize(pounds)
@pounds = pounds
end
def kilograms
(pounds * 0.453592).round
end
def stone
(pounds * 0.07142).round
end
def <=>(other)
other.instance_of?(self.class) && pounds <=> other.pounds
end
def eql?(other)
self == other
end
def hash
pounds.hash
end
end
Usingthevalue objectwithActiveRecord
weight = Weight.new(150)
person = Person.create(weight: weight)
Virtualattributes
class Weight
include Comparable
attr_reader :pounds
def initialize(pounds)
@pounds = pounds
end
def kilograms
(pounds * 0.453592).round
end
def stone
(pounds * 0.07142).round
end
def <=>(other)
other.instance_of?(self.class) && pounds <=> other.pounds
end
def eql?(other)
self == other
end
def hash
pounds.hash
end
end
Person < ActiveRecord::Base
def weight
@weight ||= Weight.new(weight_value)
end
def weight=(other_weight)
self.weight_value = other_weight.pounds
@weight = other_weight
end
end
class Person < ActiveRecord::Base
def name
@name ||= Name.new(title, first_name, middle_name, last_name,
suffix)
end
def name=(other_name)
self.title = other_name.title
self.first_name = other_name.first
self.middle_name = other_name.middle
self.last_name = other_name.last
self.suffix = other_name.suffix
@name = other_name
end
end
composed_of
class Person < ActiveRecord::Base
composed_of :name,
allow_nil: true,
mapping: [
%w(title title),
%w(first_name first),
%w(middle_name middle),
%w(last_name last),
%w(suffix suffix)
]
composed_of :weight,
allow_nil: true,
mapping: %w(weight_value pounds)
end
class Name
attr_reader :title, :first, :middle, :last, :suffix
def initialize(title, first, middle, last, suffix)
@title, @first, @middle, @last, @suffix = title, first, middle, last, suffix
end
# other stuff...
end
Questions?

More Related Content

What's hot (20)

KEY
Rspec and Rails
Icalia Labs
 
KEY
Rails Model Basics
James Gray
 
KEY
MTDDC 2010.2.5 Tokyo - Brand new API
Six Apart KK
 
PDF
Database madness with_mongoengine_and_sql_alchemy
Jaime Buelta
 
PDF
Building DSLs with Groovy
Sten Anderson
 
PPTX
Grails GORM - You Know SQL. You Know Queries. Here's GORM.
Ted Vinke
 
PDF
Symfony Day 2010 Doctrine MongoDB ODM
Jonathan Wage
 
PDF
Tame Accidental Complexity with Ruby and MongoMapper
Giordano Scalzo
 
PPTX
11. session 11 functions and objects
Phúc Đỗ
 
PDF
How to Design a Great API (using flask) [ploneconf2017]
Devon Bernard
 
PDF
ZendCon2010 Doctrine MongoDB ODM
Jonathan Wage
 
PDF
Doctrine MongoDB Object Document Mapper
Jonathan Wage
 
PDF
Symfony2 from the Trenches
Jonathan Wage
 
PDF
The Etsy Shard Architecture: Starts With S and Ends With Hard
jgoulah
 
PPTX
Indexing and Query Optimisation
MongoDB
 
PDF
#살아있다 #자프링외길12년차 #코프링2개월생존기
Arawn Park
 
ODP
Ruby on rails
Mohit Jain
 
PDF
Protocol Oriented JSON Parsing in Swift
Jason Larsen
 
KEY
The Principle of Hybrid App.
musart Park
 
Rspec and Rails
Icalia Labs
 
Rails Model Basics
James Gray
 
MTDDC 2010.2.5 Tokyo - Brand new API
Six Apart KK
 
Database madness with_mongoengine_and_sql_alchemy
Jaime Buelta
 
Building DSLs with Groovy
Sten Anderson
 
Grails GORM - You Know SQL. You Know Queries. Here's GORM.
Ted Vinke
 
Symfony Day 2010 Doctrine MongoDB ODM
Jonathan Wage
 
Tame Accidental Complexity with Ruby and MongoMapper
Giordano Scalzo
 
11. session 11 functions and objects
Phúc Đỗ
 
How to Design a Great API (using flask) [ploneconf2017]
Devon Bernard
 
ZendCon2010 Doctrine MongoDB ODM
Jonathan Wage
 
Doctrine MongoDB Object Document Mapper
Jonathan Wage
 
Symfony2 from the Trenches
Jonathan Wage
 
The Etsy Shard Architecture: Starts With S and Ends With Hard
jgoulah
 
Indexing and Query Optimisation
MongoDB
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
Arawn Park
 
Ruby on rails
Mohit Jain
 
Protocol Oriented JSON Parsing in Swift
Jason Larsen
 
The Principle of Hybrid App.
musart Park
 

Viewers also liked (14)

PDF
A System Is Not a Tree
Kevlin Henney
 
PDF
Values
BenEddy
 
PPTX
Value Objects
barryosull
 
PDF
SOLID Deconstruction
Kevlin Henney
 
ODP
#pugMi - DDD - Value objects
Simone Gentili
 
PDF
Value Objects, Full Throttle (to be updated for spring TC39 meetings)
Brendan Eich
 
PDF
Value objects in JS - an ES7 work in progress
Brendan Eich
 
PDF
The Architecture of Uncertainty
Kevlin Henney
 
PDF
Persisting Value Objects
The Software House
 
PDF
Modernsalafism saidfoudah
Yousef al-Khattab
 
PDF
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
PDF
The Rule of Three
Kevlin Henney
 
PDF
The Error of Our Ways
Kevlin Henney
 
PDF
Aggregates, Entities and Value objects - Devnology 2010 community day
Rick van der Arend
 
A System Is Not a Tree
Kevlin Henney
 
Values
BenEddy
 
Value Objects
barryosull
 
SOLID Deconstruction
Kevlin Henney
 
#pugMi - DDD - Value objects
Simone Gentili
 
Value Objects, Full Throttle (to be updated for spring TC39 meetings)
Brendan Eich
 
Value objects in JS - an ES7 work in progress
Brendan Eich
 
The Architecture of Uncertainty
Kevlin Henney
 
Persisting Value Objects
The Software House
 
Modernsalafism saidfoudah
Yousef al-Khattab
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
The Rule of Three
Kevlin Henney
 
The Error of Our Ways
Kevlin Henney
 
Aggregates, Entities and Value objects - Devnology 2010 community day
Rick van der Arend
 
Ad

Similar to Serializing Value Objects-Ara Hacopian (20)

KEY
Composed of
testflyjets
 
PPTX
6 Object Oriented Programming
Deepak Hagadur Bheemaraju
 
KEY
ActiveRecord is Rotting Your Brian
Ethan Gunderson
 
PDF
Ruby on Rails ステップアップ講座 - 大場寧子
Yasuko Ohba
 
PDF
Rails workshop for Java people (September 2015)
Andre Foeken
 
PPT
Intro to Rails ActiveRecord
Mark Menard
 
PDF
How to stop being Rails Developer
Ivan Nemytchenko
 
KEY
Ruby Internals
Burke Libbey
 
KEY
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
PDF
Implementation of EAV pattern for ActiveRecord models
Kostyantyn Stepanyuk
 
PDF
Ruby struct
Ken Collins
 
KEY
Ruby objects
Reuven Lerner
 
PDF
The Future Shape of Ruby Objects
Chris Seaton
 
PDF
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Alex Sharp
 
PDF
Effective ActiveRecord
SmartLogic
 
PDF
Ruby on Rails 中級者を目指して - 大場寧子
Yasuko Ohba
 
PPTX
Introduction to the Ruby Object Model
Miki Shiran
 
PDF
Ruby on Rails 2.1 What's New
Libin Pan
 
PDF
Perusing the Rails Source Code
Alex Kitchens
 
PPTX
Active record(1)
Ananta Lamichhane
 
Composed of
testflyjets
 
6 Object Oriented Programming
Deepak Hagadur Bheemaraju
 
ActiveRecord is Rotting Your Brian
Ethan Gunderson
 
Ruby on Rails ステップアップ講座 - 大場寧子
Yasuko Ohba
 
Rails workshop for Java people (September 2015)
Andre Foeken
 
Intro to Rails ActiveRecord
Mark Menard
 
How to stop being Rails Developer
Ivan Nemytchenko
 
Ruby Internals
Burke Libbey
 
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Implementation of EAV pattern for ActiveRecord models
Kostyantyn Stepanyuk
 
Ruby struct
Ken Collins
 
Ruby objects
Reuven Lerner
 
The Future Shape of Ruby Objects
Chris Seaton
 
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Alex Sharp
 
Effective ActiveRecord
SmartLogic
 
Ruby on Rails 中級者を目指して - 大場寧子
Yasuko Ohba
 
Introduction to the Ruby Object Model
Miki Shiran
 
Ruby on Rails 2.1 What's New
Libin Pan
 
Perusing the Rails Source Code
Alex Kitchens
 
Active record(1)
Ananta Lamichhane
 
Ad

More from SmartLogic (20)

PDF
Writing Game Servers with Elixir
SmartLogic
 
PDF
All Aboard The Stateful Train
SmartLogic
 
PDF
DC |> Elixir Meetup - Going off the Rails into Elixir - Dan Ivovich
SmartLogic
 
PDF
Monitoring Your Elixir Application with Prometheus
SmartLogic
 
PDF
Going Multi-Node
SmartLogic
 
PPTX
Kubernetes and docker
SmartLogic
 
PDF
Guide to food foraging by SmartLogic's Kei Ellerbrock
SmartLogic
 
PDF
Introduction to Type Script by Sam Goldman, SmartLogic
SmartLogic
 
PDF
How SmartLogic Uses Chef-Dan Ivovich
SmartLogic
 
PPTX
A Few Interesting Things in Apple's Swift Programming Language
SmartLogic
 
PDF
An Introduction to Reactive Cocoa
SmartLogic
 
PDF
iOS Development Methodology
SmartLogic
 
PPT
CSS Preprocessors to the Rescue!
SmartLogic
 
PDF
Deploying Rails Apps with Chef and Capistrano
SmartLogic
 
PDF
From Slacker to Hacker, Practical Tips for Learning to Code
SmartLogic
 
PDF
The Language of Abstraction in Software Development
SmartLogic
 
PDF
Android Testing: An Overview
SmartLogic
 
PPTX
Intro to DTCoreText: Moving Past UIWebView | iOS Development
SmartLogic
 
PDF
Logstash: Get to know your logs
SmartLogic
 
PDF
Intro to Accounting with QuickBooks for Startups, Software Development Compan...
SmartLogic
 
Writing Game Servers with Elixir
SmartLogic
 
All Aboard The Stateful Train
SmartLogic
 
DC |> Elixir Meetup - Going off the Rails into Elixir - Dan Ivovich
SmartLogic
 
Monitoring Your Elixir Application with Prometheus
SmartLogic
 
Going Multi-Node
SmartLogic
 
Kubernetes and docker
SmartLogic
 
Guide to food foraging by SmartLogic's Kei Ellerbrock
SmartLogic
 
Introduction to Type Script by Sam Goldman, SmartLogic
SmartLogic
 
How SmartLogic Uses Chef-Dan Ivovich
SmartLogic
 
A Few Interesting Things in Apple's Swift Programming Language
SmartLogic
 
An Introduction to Reactive Cocoa
SmartLogic
 
iOS Development Methodology
SmartLogic
 
CSS Preprocessors to the Rescue!
SmartLogic
 
Deploying Rails Apps with Chef and Capistrano
SmartLogic
 
From Slacker to Hacker, Practical Tips for Learning to Code
SmartLogic
 
The Language of Abstraction in Software Development
SmartLogic
 
Android Testing: An Overview
SmartLogic
 
Intro to DTCoreText: Moving Past UIWebView | iOS Development
SmartLogic
 
Logstash: Get to know your logs
SmartLogic
 
Intro to Accounting with QuickBooks for Startups, Software Development Compan...
SmartLogic
 

Recently uploaded (20)

PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
DOCX
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 

Serializing Value Objects-Ara Hacopian