Closed zspencer closed 1 year ago
Yea, I think it's a pretty tiny nub of indirection at the moment; but I am also hoping for a world where I can do something like render component(model)
and have that render the OrderComponent
if the model is an Order
or the CartComponent
if model
is a Cart
... But I think that's me preferring the wild and wacky world of rails naming magic.
@zspencer how are you feeling about this PR? Ok to close it, or do you want to merge it?
I have deprioritized it since you didn't seem keen and I don't have a compelling use-case yet.
Now that I've spent some more time with ViewComponents, I think I see where you were coming from here: having to do render Entire::Ass::LongComponent.new(....)
every time is kinda annoying.
The thing that I'm less sure about is replacing entire class names with a symbol, because I worry that it will make it more confusing to try to find a component if the reader of the code doesn't know about this helper. But maybe that's overly cautious of me, folks can search for the component
helper definition and figure it out?
We could go with what you have here, plus shoving the render
call into the component
helper, so one can just call:
<%= component :button , variant: :foo %>
(if we go down this route, maybe it should also be able to take a string, so that we can deal more easily with nested classes, e.g. "marketplace/tax_rate" -> Marketplace::TaxRateComponent)
Or we could go the more-typing-but-maybe-clearer version where we make a class method render
on the ApplicationComponent
, where we can do something like:
<%= ButtonComponent.render(variant: :foo) %>
Thoughts?
I've been exploring pulling out little factory helper methods into the Components themselves. This gives us a clear linkage between the class of the component being rendered while still keeping the erb light and tight.
It's more direct than a flyweight registry (like w/Furniture and Utilities), or the 'infer-the-constant/partial' that Rails leans into, and it gives us affordances for pulling common stuff into mixins or parent classes.
I do like pulling the render
into the component! I sometimes trip over the "how do we pass the block for content?!" but I think that's navigable.
I tried adding this to ApplicationComponent
:
def self.render(**kwargs, &block)
render(new(**kwargs), &block)
end
But it doesn't work, because render
is only accessible from helpers, and at the class level in the Component helpers are not available (and callingh.render
or helpers.render
also don't work, since helpers
are not available at this point).
So if we want to do something like this, we would add it as a method to our ApplicationHelper
. 🤷🏼♀️
This is probably a premature optimization, but I hate writing the entire class name out in template files! I don't know why! It just bothers me!