SlideShare uma empresa Scribd logo
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

Mais conteúdo relacionado

Semelhante a Composed of

Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
pauldix
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
pauldix
 

Semelhante a 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
 
UNIT 2 Structured query language commands
UNIT 2 Structured query language commandsUNIT 2 Structured query language commands
UNIT 2 Structured query language commands
 
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
 

Último

Research about Venice ppt for grade 6f anas
Research about Venice ppt for grade 6f anasResearch about Venice ppt for grade 6f anas
Research about Venice ppt for grade 6f anas
anasabutalha2013
 
Heuristic Evaluation of System & Application
Heuristic Evaluation of System & ApplicationHeuristic Evaluation of System & Application
Heuristic Evaluation of System & Application
Jaime Brown
 
National-Learning-Camp 2024 deped....pptx
National-Learning-Camp 2024 deped....pptxNational-Learning-Camp 2024 deped....pptx
National-Learning-Camp 2024 deped....pptx
AlecAnidul
 

Último (16)

The Design Code Google Developer Student Club.pptx
The Design Code Google Developer Student Club.pptxThe Design Code Google Developer Student Club.pptx
The Design Code Google Developer Student Club.pptx
 
Redefining Globalization, urbanisation and Localisation
Redefining Globalization, urbanisation and LocalisationRedefining Globalization, urbanisation and Localisation
Redefining Globalization, urbanisation and Localisation
 
BIT- Pinal .H. Prajapati Graphic Designer
BIT- Pinal .H. Prajapati  Graphic DesignerBIT- Pinal .H. Prajapati  Graphic Designer
BIT- Pinal .H. Prajapati Graphic Designer
 
Heidi Livengood's Professional CADD Portfolio
Heidi Livengood's Professional CADD PortfolioHeidi Livengood's Professional CADD Portfolio
Heidi Livengood's Professional CADD Portfolio
 
Claire's designing portfolio presentation
Claire's designing portfolio presentationClaire's designing portfolio presentation
Claire's designing portfolio presentation
 
Research about Venice ppt for grade 6f anas
Research about Venice ppt for grade 6f anasResearch about Venice ppt for grade 6f anas
Research about Venice ppt for grade 6f anas
 
FW25-26 Fashion Key Items Trend Book Peclers Paris
FW25-26 Fashion Key Items Trend Book Peclers ParisFW25-26 Fashion Key Items Trend Book Peclers Paris
FW25-26 Fashion Key Items Trend Book Peclers Paris
 
Common Designing Mistakes and How to avoid them
Common Designing Mistakes and How to avoid themCommon Designing Mistakes and How to avoid them
Common Designing Mistakes and How to avoid them
 
Heuristic Evaluation of System & Application
Heuristic Evaluation of System & ApplicationHeuristic Evaluation of System & Application
Heuristic Evaluation of System & Application
 
National-Learning-Camp 2024 deped....pptx
National-Learning-Camp 2024 deped....pptxNational-Learning-Camp 2024 deped....pptx
National-Learning-Camp 2024 deped....pptx
 
Pitch Presentation for Service Design in Technology
Pitch Presentation for Service Design in TechnologyPitch Presentation for Service Design in Technology
Pitch Presentation for Service Design in Technology
 
Extended Reality(XR) Development in immersive design
Extended Reality(XR) Development in immersive designExtended Reality(XR) Development in immersive design
Extended Reality(XR) Development in immersive design
 
Dos And Dont's Of Logo Design For 2024..
Dos And Dont's Of Logo Design For 2024..Dos And Dont's Of Logo Design For 2024..
Dos And Dont's Of Logo Design For 2024..
 
Spring 2024 wkrm_Enhancing Campus Mobility.pdf
Spring 2024 wkrm_Enhancing Campus Mobility.pdfSpring 2024 wkrm_Enhancing Campus Mobility.pdf
Spring 2024 wkrm_Enhancing Campus Mobility.pdf
 
Design lessons from Singapore | Volume 3
Design lessons from Singapore | Volume 3Design lessons from Singapore | Volume 3
Design lessons from Singapore | Volume 3
 
Art Nouveau Movement Presentation for Art History.
Art Nouveau Movement Presentation for Art History.Art Nouveau Movement Presentation for Art History.
Art Nouveau Movement Presentation for Art History.
 

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

Notas do Editor

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