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

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