TIL on
Cleaner conditional CSS classes with Rails’ class_names
class_names (Rails 6.1+, from ActionView::Helpers::TagHelper) builds CSS class lists from strings, arrays, and hashes: hash keys are class names, and their values decide whether each is included. It’s an alias of token_list, so use whichever reads better to you.
Instead of cramming conditionals into a string, you pass a hash:
# Before: the pattern you see in a lot of Rails apps
"nav-link #{active ? "nav-link-active" : ""}"
# => "nav-link nav-link-active" (when active is true)
# => "nav-link " (when active is false) — note the trailing space
# After:
class_names("nav-link", "nav-link-active": active)
# => "nav-link nav-link-active" (when active is true)
# => "nav-link" (when active is false) — no trailing space
And the best part? Rails’ tag builder applies the same logic to any class: option, so tag-producing helpers—tag, content_tag, link_to, button_to, and friends—accept conditional hashes for free. Here’s a real example from JobJournal’s _filter_dropdown partial:
link_to "...", class: [ "dropdown-option", "md:hidden": link[:mobile_only] ]