Skip to content

Linter Rule: Disallow unnecessary tag.attributes usage

Rule: actionview-no-unnecessary-tag-attributes

Description

Disallow using tag.attributes inside a plain HTML tag when the same result can be achieved with a tag helper like tag.input, tag.div, etc., or by adding the attributes directly to the HTML tag.

Rationale

Rails provides tag helpers (tag.input, tag.div, tag.span, etc.) that generate complete HTML elements with properly escaped attributes. Using tag.attributes inside a manually written HTML tag to achieve the same result is redundant and harder to read.

The tag.attributes helper is useful when combined with other HTML attributes or in contexts where a full tag helper cannot be used, but wrapping all attributes of a plain HTML element in tag.attributes is unnecessary and less idiomatic.

Using a tag helper or plain HTML attributes instead is:

  • More concise and idiomatic Rails.
  • Easier to read and maintain.
  • Less error-prone since the helper handles escaping and self-closing behavior.

Examples

✅ Good

erb
<input type="text" aria-label="Search">
Add an `autocomplete` attribute to improve form accessibility. Use a specific value (e.g., `autocomplete="email"`), `autocomplete="on"` for defaults, or `autocomplete="off"` to disable. (html-input-require-autocomplete)
erb
<%= tag.input type: :text, aria: { label: "Search" } %>
erb
<div id="container" class="wrapper">
  Content
</div>
erb
<%= tag.div id: "container", class: "wrapper" do %>
  Content
<% end %>
erb
<img src="<%= image_path("logo.png") %>" alt="Logo">
Prefer `image_tag` helper over manual `<img>` with dynamic ERB expressions. Use `<%= image_tag image_path("logo.png"), alt: "..." %>` instead. (erb-prefer-image-tag-helper)
erb
<%= tag.img src: image_path("logo.png"), alt: "Logo" %>

Using tag.attributes alongside regular HTML attributes is allowed:

erb
<button class="primary" <%= tag.attributes(id: @call_to_action_id, aria: { expanded: @expanded }) %>>
  Get Started!
</button>

🚫 Bad

erb
<input <%= tag.attributes(type: :text, aria: { label: "Search" }) %>>
Avoid using `tag.attributes` to set all attributes on `<input>`. Use `tag.input` or add the attributes directly to the `<input>` tag instead. (actionview-no-unnecessary-tag-attributes)
erb
<div <%= tag.attributes(id: @container_id, class: @wrapper_class) %>>
Avoid using `tag.attributes` to set all attributes on `<div>`. Use `tag.div` or add the attributes directly to the `<div>` tag instead. (actionview-no-unnecessary-tag-attributes)
Content </div>
erb
<img <%= tag.attributes(src: image_path("logo.png"), alt: "Logo") %>>
Avoid using `tag.attributes` to set all attributes on `<img>`. Use `tag.img` or add the attributes directly to the `<img>` tag instead. (actionview-no-unnecessary-tag-attributes)

References

Released under the MIT License.