Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to define the view_context without rendering the component #1926

Open
mildred opened this issue Dec 5, 2023 · 4 comments
Open

Allow to define the view_context without rendering the component #1926

mildred opened this issue Dec 5, 2023 · 4 comments

Comments

@mildred
Copy link

mildred commented Dec 5, 2023

Feature request

I'd like to be able to do something like:

comp = MyComponent.new().with_view_context(view_context)
comp.do_something_specific

That is, a way to associate the component with a view_context so I can do things like translations or access render-specific methods, but not perform the rendering step.

Motivation

I have a component that generates a HTML table. I want to make the table downloadable as a spreadsheet, but I'd like the table generation to happen within the component itself to keep all the things at the same place.

So in my rails controller, when I want to generate the spreadsheet, I create the component, then call the spreadsheet method on it that will generate the spreadsheet file. To do that I need translations, which requires the view_context.

Workaround

In my component I can define:

  def render?
    ! @skip_render
  end

  def with_no_render
    old = @skip_render
    @skip_render = true
    yield
    @skip_render = old
    self
  end

  def with_view_context(view_context)
    with_no_render do
      render_in(view_context)
    end
    self
  end

Then I can use my component like this:

    component = MyTableComponent.new(*args).with_view_context(view_context)
    add_table(spreadsheet, component.spreadsheet_table)
@reeganviljoen
Copy link
Collaborator

reeganviljoen commented Dec 8, 2023

@Spone, @camertron @joelhawksley what do you think about this,
I have seen niche circumstances where by I would have benefited from passing in a custom view_context when rendering, I do think this is niche however, so I would like to hear your thoughts on it

@joelhawksley
Copy link
Member

@reeganviljoen @mildred my gut says that this kind of functionality isn't the responsibility of ViewComponent. ViewComponent is meant to build objects that have the Single Responsibility of being passed to Rails' render.

I can see the appeal of using Slots to construct tabular data, but I think you might be better off creating some sort of PORO or model to represent your tabular data and rendering that via a ViewComponent for HTML and some other tooling for a spreadsheet format.

@camertron
Copy link
Contributor

I agree with @joelhawksley, the motivation to add this doesn't feel particularly strong, since components aren't designed to be used like shared objects. I would personally refactor your example to extract the logic into a separate class.

@reeganviljoen
Copy link
Collaborator

@camertron i feel the part about not rendering doesn't make sense but passing in a custom view_context when rendering may be useful in niche cases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants