DEV Community

Drew Bragg
Drew Bragg

Posted on

10 2

Introducing the Rails class_names method

New to Rails 6.1 is a method called class_names, from the ActionView::Helpers::TagHelper module. This handy new view helper brings one of may favorite features from Vue.js to Rails.

In Vue.js (or React via the classnames library) we can do something like this:

<div class="{item: true, item__complete: item.complete, item__over_due: !item.complete && item.overDue }">
  {{ item.name }}
</div>
Enter fullscreen mode Exit fullscreen mode

Which, assuming we have the proper css classes and item object, will give us something like this:

<!-- item.complete == false -->
<div class="item">Incomplete Item</div>

<!-- item.complete == false && item.overDue == true -->
<div class="item item__over_due">Incomplete Item</div>

<!-- item.complete == true && item.overDue == true -->
<div class="item item__complete">Complete Item</div>
Enter fullscreen mode Exit fullscreen mode

Obviously this is an overly simplified example but you get the idea. To do the same thing in Rails used to require something like this:

<%= tag.div class: "item #{item.completed? ? 'item__complete' : ''} #{!item.completed? && item.over_due? ? 'item__over_due' : ''}" do %>
  <%= item.name %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

However, the introduction of class_names simplifies this and makes it work very similarly to Vue. Now we can do something like this:

<%= tag.div class: class_names(item: true, item__complete: item.completed?, item__over_due: !item.completed? && item.over_due?) do %>
  <%= item.name %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

Additionally, class_names can take mixed argument types so the above could also be done as:

<%= tag.div class: class_names("item", { item__complete: item.completed?, item__over_due: !item.completed? && item.over_due? }) do %>
  <%= item.name %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

NOTE: The above example explicitly calls class_names for illustrative purposes. The tag (and content_tag) method uses class_names under the hood already so the above can actually be done like this:

<%= tag.div class: ["item", { item__complete: item.completed?, item__over_due: !item.completed? && item.over_due? }] do %>
  <%= item.name %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

I like this a lot and it will make building more complex conditional css class lists in Rails so much easier and cleaner. class_names is an alias of token list and you can view its documentation here.

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (1)

Collapse
 
equivalent profile image
Tomas Valent

also link_to seems to use class_name under the hood

<%= link_to "whatever", #", class: ["flex flex-ycenter", active: true] %>

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay