DEV Community

Rails Designer
Rails Designer

Posted on • Originally published at railsdesigner.com

When to Use call, erb_template, or html.erb in Rails ViewComponents?

This article was originally published on Rails Designer


ViewComponent has multiple methods to render ERB and HTML. Initially, when ViewComponent was released, there were two options:

  • a separate html.erb file, and;
  • a call method.

But since v3.0 there is another strategy you can use: erb_template. It essentially works the same as the call method, but also allows ERB or plain HTML. The goal for both call and erb_template is to eliminate an extra file. Keeping your component to one file only. Tidy and neat!

The three different rendering strategies

Let's go over how each one works and then I give some guidelines to help you choose.

erb.html

This is the default way where the template is defined in a separate .html.erb file located in the same directory as the component class. In this file you can write any ERB or HTML you need.

# app/components/example_component.html.erb
<h1>Hello, <%= @name %>!</h1>
Enter fullscreen mode Exit fullscreen mode

call

The call method can be used to write the rendering logic directly in Ruby component file. It's the option that can render HTML using Rails' ActionView content_tag or tag helpers or any other Ruby code.

# app/components/example_component.rb
class ExampleComponent < BaseComponent
  def initialize(name:)
    @name = name
  end

  def call
    content_tag(:h1, "Hello, #{@name}")
  end
end
Enter fullscreen mode Exit fullscreen mode

erb_template

You can view the erb_template strategy as a merge of the above two strategies. You can write the same HTML + ERB as with html.erb file.

# app/components/example_component.rb
class ExampleComponent < BaseComponent
  def initialize(name:)
    @name = name
  end

  erb_template <<~ERB
    <h1>Hello, <%= @name %>!</h1>
  ERB
end
Enter fullscreen mode Exit fullscreen mode

See that weird-looking <<~ERB? In Ruby it is called a “squiggly heredoc” and it allows for writing multi-line strings with automatic indentation removal.

You can of course also use other templating engines, Slim for example. That would look like this:

  # …
  slim_template <<~SLIM
    <h1>Hello, <%= @name %>!</h1>
  SLIM
  # …
Enter fullscreen mode Exit fullscreen mode

Which strategy to use?

So which strategy to use when? Over the few years of writing ViewComponent and building a library with it, I've build up some best practices when to use which strategy.

I use this as a guideline (as always with guidelines, change when it makes sense based on the context).

  1. one line of content, eg. content_tag(:h1, "Hello, #{@name}") use call;
  2. between 2 and 11 lines; use erb_template;
  3. more than 12 lines; use html.erb.

Where do I get these numbers from? Besides number 1, pretty much out of thin air. The rationale is that anything beyond 10 lines makes the component file feel more cluttered. Tucking it away in another file helps here (if you can't see it, it isn't there!). The reality is that I nowadays (since he introduction of erb_template) mostly use that strategy.

Your mileage may vary. Maybe you choose a range between 2 and 19. Fine by me! Agree on a number between yourself/your team and use that as a guideline. But having a guideline give you something to reason about.

Top comments (1)

Collapse
 
railsdesigner profile image
Rails Designer

Anything I overlooked? Something different you use? Let me know below.