Inheritance

As you start to accumulating more components in your application, you’ll natrually find yourself wanting to make little tweaks in different areas. There’s several strategies to managing these tweaks including intialization parameters, extended classes, and composition.

Initialization parameters

One way of handling slight varations to a component is by passing arguments into it upon initialization. This example shows how to change the size of a card compone.t

class MyCard < Component::Base
  def initialize(size: :small)
    @size = size
  end

  def view_template
    div(class: ["card", "card__#{@size}"]){
      yield
    }
  end
end

You might call the variants like this:

<%= render MyCard.new(size: :large) do %>
  <h1>Large Card</h1>
<% end %>

<%= render MyCard.new(size: :small) do %>
  <h1>Small Card</h1>
<% end %>

One problem with this approach is a user might pass the wrong argument into the initializer, which means you’d have to add validation to check the size.

<%= render MyCard.new(size: "blue") do %>
  <h1>Large Card</h1>
<% end %>

You could add validation logic to the initialize to check the size, but that adds a fair amount of code for not much benefit. Instead, consider extracting it out into its own component.

Variations via class inheritance and endless methods

Instead of passing a size parameter into a componet, we can use inheritence and lean on Ruby to handle it for us.

module MyCard
  class Base < Component::Base
    def size = :small
    def view_template
      div(class: ["card", "card__#{size}"]){
        yield
      }
    end
  end

  # For consistency
  Small = Base

  class Medium < Base
    def size = :medium
  end

  class Large < Base
    def size = :large
  end
end

Here’s what it looks like when rendering each from Erb.

<%= render MyCard::Large.new do %>
  <h1>Large Card</h1>
<% end %>

<%= render MyCard::Small.new do %>
  <h1>Small Card</h1>
<% end %>

When a developer tries to render a card with an invalid size, an error will be raised that MyCard::Blue doesn’t exist.

<%= render MyCard::Blue.new do %>
  <h1>Large Card</h1>
<% end %>

Since Phlex is just Ruby, we can use Ruby’s constant lookup to handle this for us which means less code for us to write and test, and better error messages for developers using the components.

Checkout in minutes

Use Apple Pay, Amazon Pay, or your credit card to order this course and we'll email you the receipt.

Purchase video course for $379