The RailsNotes Newsletter 🟥 ISSUE #12

🟥 ISSUE #12 (ViewComponents, Dynamic Navs, View Helpers, Conditional Classes)

The joy of working with a decent set of frontend components? Priceless 🧑‍🍳💋

Welcome to The RailsNotes Newsletter — Issue #12! This edition is all about ViewComponents and Rails Views! 🖼️

If you follow me on Twitter, you probably know I’m a (massive) ViewComponent fan. I think they’re great!

ViewComponents do something pretty amazing, they reduce confusion. The Rails frontend stack can feel pretty confused — It’s not hard to end up with a “partial soup”, swathes of _partials all muddled together, nested logic, random helper methods knotting things tighter… you get the idea.

ViewComponents, for me, are a great way to tackle this! They introduce a lot of clarity into the Rails frontend stack — they’re a place for logic to live, very explicit about the parameters they accept, and cleanly handle composition.

Normally I’m pretty resistant to programming stack changes (the JS ecosystems hype-cycling makes me shiver), but after working with ViewComponents, I think they’re absolutely worth checking out.

So, with all that said, this edition is about ViewComponents! I’ve collected some great articles, and you can expect more on them in the coming weeks. Let’s dive in!

FEATURED ARTICLE —

Me in zen mode, building frontends with plain ERB, TailwindCSS, Hotwire and Stimulus (and no SPA framework in sight) 😌 

This article might seem oddly specific, but I genuinely think that —

  1. It’s a great intro to ViewComponents, and

  2. It’s a great way to learn about some cool Rails frontend tricks!

In this article, I walk you through building a dynamic navbar component using plain ERB, Rails helpers and (optionally) ViewComponents — You might not have encountered many of them, but Rails has a couple of handy helper methods that make this super easy.

Specifically, we combine the current_page? helper with the class_names one, to build a component that dynamically applies CSS classes depending on which page we’re on. Towards the end of the article, I show you how to wrap this up as a ViewComponent called Ui::Nav.

If you use Rails to render your frontends (rather than using it as an API for a JS framework like React or Ember) I think you’ll love this article. It’s a great taste of what Rails has to offer, frontend-wise. Plus it’s got a nice taster for ViewComponents. Worth a read!

🌐 MORE ARTICLES —

This short article introduced ViewComponents to the world — It’s a whirlwind tour on the basic principles behind ViewComponents, a quick outline of a basic component, and some (very interesting) insights into how they’re being used inside GitHub.

The author, Joel Hawksley, is the lead developer and creator of ViewComponents, so naturally there’s some pretty great stuff in here! It’s short, sweet, and packed with interesting info.

If you’re new to ViewComponents and want a taste of how they work, I think this is a great place to start! Josef has written a great beginner guide, walking you through the basics, including passing components into slots and writing unit tests for them.

This article does a great job of elucidating the “why” behind ViewComponents — why are they helpful? why use them? Ryan’s preamble does a great job setting up the context for why ViewComponents are useful, and I think it’s a great complement to the other articles here.

Included in the article are some handy code examples, which are great for understanding the concepts and ideas that underpin ViewComponents.

— ⚒️ HANDY TIP — 

→ Apply CSS classes conditionally with Rails class_names

It’s pretty common to dynamically set classes in your Rails views, based on a variable. Maybe if current_user.admin? you want to make a link visible, or if current_page?(root_path) you want to highlight something in the navbar.

Rails has a handy way to do this! Rather than embedding <%= ERB tags %> directly, you can use Rails` inbuilt view helpers to dynamically assign classes, like so —

# text-red-500 applied, shadow-lg not
#
<%= tag.p class: [
  "text-red-500" : true,
  "shadow-lg" : false
] %>

# output
<p class="text-red-500"></p>