1

I am trying to add a dynamic class to a link_to in Rails 7. I have the following code, but it's not inserting the appropriate content based on the request.env["PATH_INFO"]...

<ul>
        <% %w[blog headlines network].each do |nav_link| %>
        <%= added_class = request.env["PATH_INFO"] == nav_link ? "nav_current" : nil %>
          <li class="btn"><%= link_to "#{nav_link}".capitalize, "/#{nav_link}", id: "nav_main", class: "btn btn_nav #{added_class}" %></li>
        <% end %>
      </ul>

However, the resulting HTML is:

      <ul>
          <li class="btn"><a id="nav_main" class="btn btn_nav " href="/blog">Bog</a></li>
          <li class="btn"><a id="nav_main" class="btn btn_nav " href="/headlines">Headlines</a></li>
          <li class="btn"><a id="nav_main" class="btn btn_nav " href="/network">Network</a></li>
      </ul>

As you can see, the added_class doesn't get inserted. Any ideas?

Matteo
  • 1,136
  • 1
  • 16
  • 36
  • 1
    You might want to have a look at [`link_to_unless_current`](https://api.rubyonrails.org/v5.1/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to_unless_current) and the other `URLHelper' methods.` because `link_to_unless_current` exists for exactly your use case... – spickermann Aug 02 '22 at 03:29
  • @spickerman - Good point. This is exactly what this use case needs. It is easy to assign a class to this helper method. +1 for teaching! – Matteo Aug 05 '22 at 03:57

2 Answers2

0

request.env['PATH_INFO'] contains a leading / (at least on Rails 7; and IIRC on previous versions as well)

That means that if you are visiting localhost:3000/blog, request.env['PATH_INFO'] is /blog, not blog.

The following code should fix it:

<ul>
  <% %w[blog headlines network].each do |nav_link| %>
    <% added_class = request.env["PATH_INFO"] == "/#{nav_link}" ? "nav_current" : nil %>
    <li class="btn"><%= link_to "#{nav_link}".capitalize, "/#{nav_link}", id: "nav_main", class: "btn btn_nav #{added_class}" %></li>
  <% end %>
</ul>
Ankit
  • 6,772
  • 11
  • 48
  • 84
  • You beat me to it. Thanks for your contribution. I would point out the `nil` in your code that I had in the beginning. `Nil` returns erroneously. You need to insert `""` instead. – Matteo Aug 02 '22 at 02:32
  • 1
    I don't think that is needed. Even with `nil`, it works for me. I just see extra space in the class attribute. – Ankit Aug 02 '22 at 02:40
  • @Ankit the other approach that would work would be to use the Rails helpers`controller_name` or `controller_path`, which for instance, would return `blog` and you would not have to worry about matching with the `/`. Just an alternative. – C. Smith Mar 30 '23 at 18:17
0

Ok, so the following code does what I wanted it to. It injects a custom class into the link tag so that I can track the current button and style it differently... :

      <ul>
        <% %w[blog headlines network].each do |nav_link| %>
        <% add_class = request.env['PATH_INFO'] == "/#{nav_link}" ? "nav_current" : "" %>
          <li class="btn"><%= link_to "#{nav_link}".capitalize, "/#{nav_link}", id: "nav_main", class: "btn btn_nav #{add_class}" %></li>
        <% end %>
      </ul>

No Javascript necessary.

Matteo
  • 1,136
  • 1
  • 16
  • 36