Rails 7 transforms a Ruby hash into HTML attributes for ERB interpolation


One of the basic things we learn as a Rails developer is how to interpolate bits and pieces of Ruby code into our template file, which is ERB. There are many other template engines apart from ERB, such as HAML and Slim, but since ERB is the default for Rails, the examples shown below use the ERB syntax.

Let us consider the example of displaying an image of my pet dog 🐶. Assume that we have the following attributes in a hash.

  pet = { image_url: "https://data.whicdn.com/images/23516263/original.jpg",
  name: "Pommya", breed: "Pomeranian", color: "white" }

Before

The above hash values can be added to HTML img tag as below:

<img src="<%= pet[:image_url] %>", alt="<%= pet[:name] %>",
  data-breed="<%= pet[:breed] %>", data-color="<%= pet[:color] %>">

=> <img src="https://data.whicdn.com/images/23516263/original.jpg" alt="Pommya" data-breed="Pomeranean" data-color="white">

We can also use tag or content_tag methods to replace HTML tags with Ruby code. Here we define all the img tag attributes using a hash.

# Using tag helper

<%= tag.img src: pet[:image_url], alt: pet[:name],
  data: { breed: pet[:breed], color: pet[:color] } %>

# Using content_tag helper

<%= content_tag(:img, "", src: pet[:image_url], alt: pet[:name],
  data: { breed: pet[:breed], color: pet[:color] }) %>

=> <img src="https://data.whicdn.com/images/23516263/original.jpg" alt="Pommya" data-breed="Pomeranean" data-color="white">

After

Rails 7 has added the ability to transform a Ruby hash into HTML attributes for ERB interpolation by using the ActionView::Helpers::TagHelper#tag_options implementation.

This will allow us to mix Ruby hash into HTML tags along with other HTML attributes to achieve the same result in the ERB.

Suppose we want to add an inline style to an HTML element and we prefer to do it using normal HTML attributes.

# Using tag.attributes

<img <%= tag.attributes src: pet[:image_url], alt: pet[:name],
  data: { breed: pet[:breed], color: pet[:color] } %> >

=> <img src="https://data.whicdn.com/images/23516263/original.jpg" alt="Pommya" data-breed="Pomeranean" data-color="white">

# Adding inline style

<img <%= tag.attributes src: pet[:image_url], alt: pet[:name],
         data: { breed: pet[:breed], color: pet[:color] } %>
         style="border-radius: 8px; background-color: white;" >

=> <img src="https://data.whicdn.com/images/23516263/original.jpg" alt="Pommya" data-breed="Pomeranean" data-color="white" style="border-radius: 8px; background-color: white;">

With this change, we can add inline style using the normal HTML style attribute.