SlideShare a Scribd company logo
1 of 12
composed_of
flat_data.convert_to(rich_ruby_object)



   most material from Chad Fowler’s “Rails Recipes”, pragprog.com
The Needs
• You have a simple model attribute that
  needs additional behavior but don’t want to
  create an additional ActiveRecord model
• You need to store structured data in the
  same table as your model but treat it as a
  first-class, normalized object
composed_of
class SomeModel < ActiveRecord::Base
  composed_of :some_attribute,
    :class_name => 'SomeSpecialClass',
    :mapping => [%w(model_attr_name special_class_attr)]
end

“Add some_attribute, composed of SomeSpecialClass,
and map SomeModel’s model_attr_name field to
special_class_attr.”
CourseRecord class
class CourseRecord < ActiveRecord::Base
  composed_of :grade,
    :mapping => %w(letter_grade letter_grade)
end
Grade class
class Grade
  attr_accessor :letter_grade

  def initialize(letter_grade)
      @letter_grade = letter_grade
  end
end
class Grade
                             include Comparable
                             attr_accessor :letter_grade
 course_records
                            def initialize(letter_grade)
                               @letter_grade = letter_grade
id
                            end
course_id
                          end
student_id
letter_grade



  class CourseRecord < ActiveRecord::Base
    composed_of :grade,
      :mapping => %w(letter_grade letter_grade)
  end
Things to remember


• include Comparable and define <=> in
  order to compare composed_of classes
class Grade
                       Grade class
   include Comparable

  SORT_ORDER = ["F", "D", "D", "B", "A"].inject({}) {|h, letter|
    h.update "#{letter}-" => h.size
    h.update letter => h.size
    h.update "#{letter}+" => h.size
  }

  def <=>(other)
    SORT_ORDER[letter_grade.downcase] <=>
    SORT_ORDER[other.letter_grade.downcase]
  end
end
Things to remember

• composed_of objects are value objects and
  are immutable!
• Create a new object to change the AR
  model’s composed_of attr
Structured Data
    person        class Person < ActiveRecord::Base
id
first_name
                    composed_of :address, :mapping =>
last_name                 [ %w(address_street street),
address_street
address_city                 %w(address_city city),
address_state                %w(address_state state),
address_country
email                        %w(address_country country) ]
                  end
class Address     Address class
  attr_accessor :street, :city, :state, :country

  def initialize(street, city, state, country)
       @street = street
       @city = city
       @state = state
       @country = country
 end

 def full_address
   “#{street} #{city}, #{state} #{country}”
 end
end
The Results
•   Keep your Models DRY and put the responsibilities
    and behaviors where they belong

•   Reuse the composed_of models instead of
    repeating methods in multiple classes

•   Store structured data flatly but treat it as a first-
    class Ruby object

•   Don’t garbage-up your models with lots of
    “formatting” methods like :full_address

More Related Content

Similar to Composed of

Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Pedro Cunha
 
Intro to Rails ActiveRecord
Intro to Rails ActiveRecordIntro to Rails ActiveRecord
Intro to Rails ActiveRecordMark Menard
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
Rapid Prototyping with PEAR
Rapid Prototyping with PEARRapid Prototyping with PEAR
Rapid Prototyping with PEARMarkus Wolff
 
Implementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord modelsImplementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord modelsKostyantyn Stepanyuk
 
Business Rules with Brick
Business Rules with BrickBusiness Rules with Brick
Business Rules with Brickbrian d foy
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsEleanor McHugh
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaiMasters
 
model.search: customize your own search logic
model.search: customize your own search logicmodel.search: customize your own search logic
model.search: customize your own search logicTse-Ching Ho
 
Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2RORLAB
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
EPiServer report generation
EPiServer report generationEPiServer report generation
EPiServer report generationPaul Graham
 

Similar to Composed of (20)

Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
SQL.ppt
SQL.pptSQL.ppt
SQL.ppt
 
Framework
FrameworkFramework
Framework
 
Working with shapes
Working with shapesWorking with shapes
Working with shapes
 
Intro to Rails ActiveRecord
Intro to Rails ActiveRecordIntro to Rails ActiveRecord
Intro to Rails ActiveRecord
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Rails <form> Chronicle
Rails <form> ChronicleRails <form> Chronicle
Rails <form> Chronicle
 
Rapid Prototyping with PEAR
Rapid Prototyping with PEARRapid Prototyping with PEAR
Rapid Prototyping with PEAR
 
Implementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord modelsImplementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord models
 
Business Rules with Brick
Business Rules with BrickBusiness Rules with Brick
Business Rules with Brick
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
Why ruby
Why rubyWhy ruby
Why ruby
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
 
D8 Form api
D8 Form apiD8 Form api
D8 Form api
 
model.search: customize your own search logic
model.search: customize your own search logicmodel.search: customize your own search logic
model.search: customize your own search logic
 
Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
EPiServer report generation
EPiServer report generationEPiServer report generation
EPiServer report generation
 

Recently uploaded

Call Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts Service
Call Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts ServiceCall Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts Service
Call Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts Servicejennyeacort
 
Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...
Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...
Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...home
 
WAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past QuestionsWAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past QuestionsCharles Obaleagbon
 
Cheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk Gurgaon
Cheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk GurgaonCheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk Gurgaon
Cheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk GurgaonDelhi Call girls
 
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130Suhani Kapoor
 
Cheap Rate Call girls Malviya Nagar 9205541914 shot 1500 night
Cheap Rate Call girls Malviya Nagar 9205541914 shot 1500 nightCheap Rate Call girls Malviya Nagar 9205541914 shot 1500 night
Cheap Rate Call girls Malviya Nagar 9205541914 shot 1500 nightDelhi Call girls
 
The history of music videos a level presentation
The history of music videos a level presentationThe history of music videos a level presentation
The history of music videos a level presentationamedia6
 
NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...
NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...
NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...Amil baba
 
Fashion trends before and after covid.pptx
Fashion trends before and after covid.pptxFashion trends before and after covid.pptx
Fashion trends before and after covid.pptxVanshNarang19
 
MASONRY -Building Technology and Construction
MASONRY -Building Technology and ConstructionMASONRY -Building Technology and Construction
MASONRY -Building Technology and Constructionmbermudez3
 
Kindergarten Assessment Questions Via LessonUp
Kindergarten Assessment Questions Via LessonUpKindergarten Assessment Questions Via LessonUp
Kindergarten Assessment Questions Via LessonUpmainac1
 
VIP Kolkata Call Girl Gariahat 👉 8250192130 Available With Room
VIP Kolkata Call Girl Gariahat 👉 8250192130  Available With RoomVIP Kolkata Call Girl Gariahat 👉 8250192130  Available With Room
VIP Kolkata Call Girl Gariahat 👉 8250192130 Available With Roomdivyansh0kumar0
 
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdfThe_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdfAmirYakdi
 
VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...
VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...
VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...Suhani Kapoor
 
Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...
Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...
Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...Yantram Animation Studio Corporation
 
A level Digipak development Presentation
A level Digipak development PresentationA level Digipak development Presentation
A level Digipak development Presentationamedia6
 
DragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptxDragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptxmirandajeremy200221
 
Best VIP Call Girls Noida Sector 47 Call Me: 8448380779
Best VIP Call Girls Noida Sector 47 Call Me: 8448380779Best VIP Call Girls Noida Sector 47 Call Me: 8448380779
Best VIP Call Girls Noida Sector 47 Call Me: 8448380779Delhi Call girls
 
VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...
VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...
VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...Suhani Kapoor
 

Recently uploaded (20)

Call Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts Service
Call Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts ServiceCall Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts Service
Call Girls In Safdarjung Enclave 24/7✡️9711147426✡️ Escorts Service
 
Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...
Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...
Recommendable # 971589162217 # philippine Young Call Girls in Dubai By Marina...
 
WAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past QuestionsWAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past Questions
 
young call girls in Vivek Vihar🔝 9953056974 🔝 Delhi escort Service
young call girls in Vivek Vihar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Vivek Vihar🔝 9953056974 🔝 Delhi escort Service
young call girls in Vivek Vihar🔝 9953056974 🔝 Delhi escort Service
 
Cheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk Gurgaon
Cheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk GurgaonCheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk Gurgaon
Cheap Rate ➥8448380779 ▻Call Girls In Iffco Chowk Gurgaon
 
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
 
Cheap Rate Call girls Malviya Nagar 9205541914 shot 1500 night
Cheap Rate Call girls Malviya Nagar 9205541914 shot 1500 nightCheap Rate Call girls Malviya Nagar 9205541914 shot 1500 night
Cheap Rate Call girls Malviya Nagar 9205541914 shot 1500 night
 
The history of music videos a level presentation
The history of music videos a level presentationThe history of music videos a level presentation
The history of music videos a level presentation
 
NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...
NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...
NO1 Famous Amil Baba In Karachi Kala Jadu In Karachi Amil baba In Karachi Add...
 
Fashion trends before and after covid.pptx
Fashion trends before and after covid.pptxFashion trends before and after covid.pptx
Fashion trends before and after covid.pptx
 
MASONRY -Building Technology and Construction
MASONRY -Building Technology and ConstructionMASONRY -Building Technology and Construction
MASONRY -Building Technology and Construction
 
Kindergarten Assessment Questions Via LessonUp
Kindergarten Assessment Questions Via LessonUpKindergarten Assessment Questions Via LessonUp
Kindergarten Assessment Questions Via LessonUp
 
VIP Kolkata Call Girl Gariahat 👉 8250192130 Available With Room
VIP Kolkata Call Girl Gariahat 👉 8250192130  Available With RoomVIP Kolkata Call Girl Gariahat 👉 8250192130  Available With Room
VIP Kolkata Call Girl Gariahat 👉 8250192130 Available With Room
 
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdfThe_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
 
VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...
VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...
VIP Russian Call Girls in Saharanpur Deepika 8250192130 Independent Escort Se...
 
Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...
Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...
Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...
 
A level Digipak development Presentation
A level Digipak development PresentationA level Digipak development Presentation
A level Digipak development Presentation
 
DragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptxDragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptx
 
Best VIP Call Girls Noida Sector 47 Call Me: 8448380779
Best VIP Call Girls Noida Sector 47 Call Me: 8448380779Best VIP Call Girls Noida Sector 47 Call Me: 8448380779
Best VIP Call Girls Noida Sector 47 Call Me: 8448380779
 
VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...
VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...
VIP College Call Girls Gorakhpur Bhavna 8250192130 Independent Escort Service...
 

Composed of

  • 1. composed_of flat_data.convert_to(rich_ruby_object) most material from Chad Fowler’s “Rails Recipes”, pragprog.com
  • 2. The Needs • You have a simple model attribute that needs additional behavior but don’t want to create an additional ActiveRecord model • You need to store structured data in the same table as your model but treat it as a first-class, normalized object
  • 3. composed_of class SomeModel < ActiveRecord::Base composed_of :some_attribute, :class_name => 'SomeSpecialClass', :mapping => [%w(model_attr_name special_class_attr)] end “Add some_attribute, composed of SomeSpecialClass, and map SomeModel’s model_attr_name field to special_class_attr.”
  • 4. CourseRecord class class CourseRecord < ActiveRecord::Base composed_of :grade, :mapping => %w(letter_grade letter_grade) end
  • 5. Grade class class Grade attr_accessor :letter_grade def initialize(letter_grade) @letter_grade = letter_grade end end
  • 6. class Grade include Comparable attr_accessor :letter_grade course_records def initialize(letter_grade) @letter_grade = letter_grade id end course_id end student_id letter_grade class CourseRecord < ActiveRecord::Base composed_of :grade, :mapping => %w(letter_grade letter_grade) end
  • 7. Things to remember • include Comparable and define <=> in order to compare composed_of classes
  • 8. class Grade Grade class include Comparable SORT_ORDER = ["F", "D", "D", "B", "A"].inject({}) {|h, letter| h.update "#{letter}-" => h.size h.update letter => h.size h.update "#{letter}+" => h.size } def <=>(other) SORT_ORDER[letter_grade.downcase] <=> SORT_ORDER[other.letter_grade.downcase] end end
  • 9. Things to remember • composed_of objects are value objects and are immutable! • Create a new object to change the AR model’s composed_of attr
  • 10. Structured Data person class Person < ActiveRecord::Base id first_name composed_of :address, :mapping => last_name [ %w(address_street street), address_street address_city %w(address_city city), address_state %w(address_state state), address_country email %w(address_country country) ] end
  • 11. class Address Address class attr_accessor :street, :city, :state, :country def initialize(street, city, state, country) @street = street @city = city @state = state @country = country end def full_address “#{street} #{city}, #{state} #{country}” end end
  • 12. The Results • Keep your Models DRY and put the responsibilities and behaviors where they belong • Reuse the composed_of models instead of repeating methods in multiple classes • Store structured data flatly but treat it as a first- class Ruby object • Don’t garbage-up your models with lots of “formatting” methods like :full_address

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n