Weird Rails partials bug with View Components

Weird Rails partials bug with View Components

Content rendered outside partials with View Components helpers

ยท

3 min read

Yesterday, during my regular Avo coding sessions I ran into a strange-looking bug.

Context

I created a View Component names ResourceShow inside which I used a helper a_link that renders a button-looking link using a helper and a regular Rails partial. The code looks like this:

# application_helper.rb
module ApplicationHelper
  def a_link(label, url = nil, **args, &block)
    args[:style] = 'border: 1px solid red;'

    if block_given?
      url = label
    end

    locals = {
      label: label,
      url: url,
      args: args,
    }

    if block_given?
      render layout: 'layouts/a_link', locals: locals do
        capture(&block)
      end
    else
      render partial: 'layouts/a_link', locals: locals
    end
  end
end
# application_helper.rb
<% if (block = yield).empty? %>
  <%= link_to label, url, **args %>
<% else %>
  <%= link_to url, **args do %>
    <%= yield %>
  <% end %>
<% end %>

So running this <%= a_link '/' do %>Content inside the button<% end %> should render a basic button. Because we'll be using this helper inside a view component, by checking their docs on helpers we need to prepend the helpers. function, so we'll do <%= helpers.a_link '/' do %>Content inside the button<% end %>.

But instead of our plain button, we'll get this weird bug.

image.png

The content inside the block will get duplicated and prepended outside the whole button ๐Ÿคฏ

The fix

You just need to stop using the helpers prepend method in the template and include the helper module in the view component ๐Ÿ”ฅ.

# app/components/hello_component.rb
class HelloComponent < ViewComponent::Base
  include ApplicationHelper
end
# app/components/hello_component.html.erb
<%= a_link '/' do %>
  Content inside the button
<% end %>

image.png

I'm writing this hoping that this will help someone in the future not lose their minds with this weird partials bug.

Stay sane, stay positive โœŒ๏ธ

Photo by Greta Pichetti

Source code on GitHub