Open BlakeWilliams opened 3 years ago
I've spiked this out a bit here: https://github.com/BlakeWilliams/view_component-rails-test/pull/1/files (PR's showing off other ideas or approaches are welcome)
Some take-aways:
_
prefixed file names for use as partials doesn't feel like the correct approach for components.render "users/profile, user: user"
instead of render Users::Profile.new(user)
has some limitations, like requiring that component arguments are keyword arguments.
render User::Profile.new(user)
translate to render "user/profile
? The component would be required to change the initializer from def initialize(user)
to def initialize(user:)
.I think the flexibility of view components (e.g. user defined initializers) may make it more challenging to make them work with Rails as seamlessly as we'd like, but I'll keep experimenting with it.
@BlakeWilliams I actually prefer the explicit object instantiation over using strings. Makes it easier to refactor and also makes it clearer that it is a "component" and not a partial. Would be OK with being able to use both ways though as a matter of user preference.
At the moment I feel like trying to unify view components with the existing rails approach to views seems like it would be a bit inconsistent . View_component encourages a more django-like "views and templates" approach that doesn't seem like it would mesh well. Perhaps I just need to play around more with it and see how it would work in practice.
Just found out about this issue while I've been looking around.
Some observations here:
View
namespace right now. I wonder if we should promote using this namespace so that we don't pollute the top-level object namespace. Even if we don't do that, it'd be good for the lookup to support a default namespace.with_collection
, so I can't imagine it's too much of a problem.# app/controllers/some_controller.rb
def index
assigns.posts = Post.all
# Behind the scenes, the controller will do this:
# render Index.new, **assigns
end
Effectively, we'd be emulating the idea that you build up instance variables in the controller and pass them to the view, but we'd instead be doing this through assigns
so that anything passed to the view (component) is still contained to that component.
ViewComponent::Base
and including something that makes sure helpers are still availableRelevant wizardry using Phlex: https://fly.io/ruby-dispatch/component-driven-development-on-rails-with-phlex/ I'm posting it here, since it might give some ideas on the above points.
So awesome to see this come to life!
Ditto that! It would be amazing to use ViewComponent as a view and view model layer in Rails 🎉
@bradgessler @joeldrapper giving dhh's closing of the Rails PR, what do you think about writing a shared gem for implicit renderable rendering that both ViewComponent and Phlex could share?
Yeah, that makes sense to me. Phlex-Rails could depend on that gem.
@joeldrapper great. Want to pick a name? rails-implicit-renderable-rendering
?
@joeldrapper @joelhawksley I really liked this idea, and just put together some code here, mind taking a look https://github.com/reeganviljoen/render_kit
Currently, components live in a dedicated
app/components
directory. This has worked well so far, but we'd like to explore a more unified approach.This isn't set in stone, but the goals would be to:
app/views
render "users/show", user: current_user
to render a component instead of explicitly referring to the component class. e.g. This would be equivalent torender Users::Show.new(user: current_user)
Component
suffix from components so their names have a 1-to-1 mapping to view directories. e.g.app/views/users/user.rb
would map toclass Users::User < ViewComponent::Base
A more complete example may look like:
part of https://github.com/github/view_component/issues/617