Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Candy on Rails - Polymorphism and Rails 5

Candy on Rails - Polymorphism and Rails 5

A pragmatic look at how Polymorphism can be utilized

Avatar for Michael Cain

Michael Cain

April 17, 2018
Tweet

More Decks by Michael Cain

Other Decks in Education

Transcript

  1. CANDY ON RAILS - POLYMORPHISM AND RAILS 5 ▸ Brand-new

    to Ruby on Rails ▸Not-so-new to Ruby on Rails and are looking for a refresher ▸In it for the free candy WHO IS THIS FOR?
  2. CANDY ON RAILS - POLYMORPHISM AND RAILS 5 ▸What is

    polymorphism? ▸Why is polymorphism useful? ▸Basic Polymorphism ▸Advanced polymorphism WHAT WE’RE COVERING
  3. CANDY ON RAILS - POLYMORPHISM AND RAILS 5 \ ˌPÄ-LĒ-ˈMȮR-ˌFI-ZƏM

    \: the quality or state of existing in or assuming different forms Merriam-Webster Dictionary
  4. CANDY ON RAILS - POLYMORPHISM AND RAILS 5 POLYMORPHIC ASSOCIATIONS

    [P]olymorphic associations…can belong to more than one other model, on a single association. Ruby On Rails Guide http://guides.rubyonrails.org/ association_basics.html#polymorphic-associations
  5. CANDY ON RAILS - POLYMORPHISM AND RAILS 5 FLEXIBLE ‣Polymorphism

    frees us from tightly coupling models together (:foo_id not a required attribute for :belongs_to) DRY ‣Rails provides us with concise solutions for variable model associations. Don’t Repeat Yourself
  6. ToffeeLove Uchi-Pizzelles Ruby’s SessionCookies A rich, fun mixture of English

    toffee, dark chocolate and a hint of wasabi A light, Italian shortbread with a taste of anise and a maple glaze Vienna-style finger cookies with a vanilla cream-cheese frosting (Vanilla, Lemon or Strawberry)
  7. ‣ Our signature goodies are made by hand and our

    recipes are open source; we keep track of which chefs make which goodies ‣ We package our goodies in: ‣ Bags - 5 count ‣ Gift Boxes - 10 count ‣ Rail Cars - 20 count CANDY ON RAILS - POLYMORPHISM AND RAILS 5
  8. class Bag < ApplicationRecord belongs_to :address has_many :goodies end class

    GiftBox < ApplicationRecord belongs_to :address has_many :goodies end class RailCar < ApplicationRecord belongs_to :address has_many :goodies end class Address < ApplicationRecord has_many :bags has_many :gift_boxes has_many :rail_cars end class Goody < ApplicationRecord belongs_to :bags belongs_to :gift_box belongs_to :rail_car end Manually managed nils Each package requires an id Hard to scale
  9. class Goody < ApplicationRecord belongs_to :package, polymorphic: true end class

    RailCar < ApplicationRecord belongs_to :address has_many :goodies, as: :package end class GiftBox < ApplicationRecord belongs_to :address has_many :goodies, as: :package end class Bag < ApplicationRecord belongs_to :address has_many :goodies, as: :package end DRY Flexible Easy to scale
  10. POLYMORPHISM UNDER THE HOOD SELECT "goodies".* FROM "goodies" WHERE "goodies"."package_id"

    = 1 AND "goodies"."package_type" = 'Bag' BAG.FIRST.GOODIES.TO_SQL
  11. POLYMORPHISM UNDER THE HOOD SELECT "candies".* FROM "candies" WHERE "candies"."package_id"

    = 3 AND "candies"."package_type" = ‘GiftBox ‘ GIFTBOX.FIND(3).GOODIES.TO_SQL
  12. COST/BENEFIT OF INTRODUCING POLYMORPHISM CANDY ON RAILS - POLYMORPHISM AND

    RAILS 5 BENEFIT COST ‣ Creates Flexibility/DRY ‣ Isolate Complexity ‣ Abstracts association ‣ Rails “magic” difficulties (:inverse_of)
  13. COST/BENEFIT OF INTRODUCING POLYMORPHISM CANDY ON RAILS - POLYMORPHISM AND

    RAILS 5 THINGS TO CONSIDER ‣ Is your new model “sufficiently original”? ‣ Do you have to do decide now? ‣ What are the consequences of “vanilla” associations? ‣ What’s best for the user?
  14. POTENTIAL ALTERNATIVE TO INTRODUCING POLYMORPHISM CANDY ON RAILS - POLYMORPHISM

    AND RAILS 5 JSON Object as attribute create_table "package", force: :cascade do |t| t.integer "order_id" t.string “shipping_type" t.jsonb “package_details” t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["order_id"], name: "index_packages_on_order_id" end
  15. Our goodies are a hit! Our customers are interested in

    pertinent details of some of our goody types: CANDY ON RAILS - POLYMORPHISM AND RAILS 5 ‣ Taffy ‣ Salt water or Regular? ‣ Flavor ‣ Custom colors ‣ Cookies ‣ Vegan? ‣ Gluten-free? ‣ Allergies
  16. Our Goody model now needs to accommodate specific model types,

    so we can create another polymorphic relationship: CANDY ON RAILS - POLYMORPHISM AND RAILS 5 class Goody < ApplicationRecord belongs_to :package, polymorphic: true belongs_to :confection, polymorphic: true, optional: true end
  17. We can create a :has_may relationship like this: CANDY ON

    RAILS - POLYMORPHISM AND RAILS 5 class RailCar < ApplicationRecord belongs_to :address has_many :goodies, as: :package has_many :cookies, through: :goodies, source: :confection, source_type:’Cookie’ end class Cookie < ApplicationRecord has_one :goody, as: :confection end
  18. :belongs_to magic still works with polymorphism CANDY ON RAILS -

    POLYMORPHISM AND RAILS 5 class Bag < ApplicationRecord belongs_to :order has_many :goodies, as: :package has_many :cookies, through: :goodies, source::confection, source_type: 'Cookie' has_many :taffies, through: :goodies, source::confection, source_type: 'Taffy' accepts_nested_attributes_for :goodies accepts_nested_attributes_for :cookies accepts_nested_attributes_for :taffies end bag = Bag.find(233) bag.cookies << Cookie.new(<cookie attrs>)
  19. MAKING YOUR POLYMORPHISM A CONCERN CANDY ON RAILS - POLYMORPHISM

    AND RAILS 5 require 'active_support/concern' module GoodyPackageManager extend ActiveSupport::Concern included do belongs_to :order has_many :goodies, as: :package has_many :cookies, through: :goodies, source: :confection, source_type: 'Cookie' has_many :taffies, through: :goodies, source: :confection, source_type: 'Taffy' accepts_nested_attributes_for :goodies accepts_nested_attributes_for :cookies accepts_nested_attributes_for :taffies end end
  20. CANDY ON RAILS - POLYMORPHISM AND RAILS 5 class Bag

    < ApplicationRecord include GoodyPackageManager end class GiftBox < ApplicationRecord include GoodyPackageManager end class RailCar < ApplicationRecord include GoodyPackageManager end
  21. CANDY ON RAILS - POLYMORPHISM AND RAILS 5 TAKE AWAYS

    ‣ Polymorphism is a useful tool to manage complex associations ‣ Like any abstraction, it should be used sparingly ‣ Consider alternatives before implementing ‣ Remember the user