Compositions
Inheritance is a useful tool for managing the complexity of Phlex views and components, but it can also lead to tight coupling and make it difficult to reuse components across different contexts. Compositions, on the other hand, offer a flexible and modular approach to building complex views.
Recall the Card
component we created earlier.
class Card < Phlex::Component
def around_template(&)
super do
div(class: "p-4 shadow rounded bg-color-neutral-100", &)
end
end
# Having only a yield in the method will render whatever is passed into it
# from the rendering call.
def view_template
yield
end
end
Then we started constructing the ProfileCard
component, which actually mixes several concerns poorly.
🔓 Unlock content
Pre-order this course to unlock this video, source code, and content.
class ProfileCard < ▓▓▓▓
def ▓▓▓▓▓(&)
▓▓▓(class: "text-xl font-bold", &)
end
def ▓▓▓▓(&)
▓▓(&)
end
def ▓▓▓▓(name, &)
▓▓(class: "font-bold") { name }
▓▓ { yield }
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
yield
end
end
▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓
Decouple ProfileCard
from Card
▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
class ProfileCard < ▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(&)
super { ▓▓▓▓▓▓ ▓▓▓▓.▓▓▓(&)}
end
def ▓▓▓▓▓(&)
▓▓▓(class: "text-xl font-bold", &)
end
def ▓▓▓▓(&)
▓▓(&)
end
def ▓▓▓▓(name, &)
▓▓(class: "font-bold") { name }
▓▓ { yield }
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
yield
end
end
▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓ ▓ ▓▓▓▓▓
Extract List
Component
▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
class List < ▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(&)
super { ▓▓(&)}
end
def ▓▓▓▓(name, &)
▓▓(class: "font-bold") { name }
▓▓ { yield }
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
yield
end
end
▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓
class ProfileCard < ▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(&)
super { ▓▓▓▓▓▓ ▓▓▓▓.▓▓▓(&)}
end
def ▓▓▓▓▓(&)
▓▓▓(class: "text-xl font-bold", &)
end
def ▓▓▓▓(&)
▓▓▓▓▓▓ ▓▓▓▓.▓▓▓(&)
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
yield
end
end
▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓
<%= ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓.▓▓▓ do |▓▓▓▓|
▓▓▓▓.▓▓▓▓▓ { "Profile" }
▓▓▓▓.▓▓▓▓ do |▓▓▓▓|
▓▓▓▓.▓▓▓▓("Name") { "John Doe" }
▓▓▓▓.▓▓▓▓("Email") { "john@example.com" }
end
end %>
▓▓▓ ▓▓▓▓
Eliminate render
boilerplate
▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓ ▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓
▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓
module Components
extend ▓▓▓▓▓::▓▓▓
end
▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓
class ProfileCard < ▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(&)
super { ▓▓▓▓(&)}
end
def ▓▓▓▓▓(&)
▓▓▓(class: "text-xl font-bold", &)
end
def ▓▓▓▓(&)
▓▓▓▓(&)
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
yield
end
end