Unlocking Rails cycle: A Hidden Gem for Views.

Published on September 16, 2025
Written by Victor Cobos

When you’re working with Rails views, it’s easy to fall into habits: loops for collections, conditionals for styles, partials for structure. But tucked away in ActionView is a little helper that often gets overlooked — cycle.

If you’ve ever written if index.even? ... else ... end just to style alternating rows, there’s a cleaner way. And once you start using it, you’ll find plenty of creative uses.

Understanding cycle: What Does It Do?

At its core, cycle rotates through a list of values each time it’s called. Think of it as a round-robin generator for your views.

A classic example looks like this:

<tr class="<%= cycle("odd", "even") %>">
  <td>Item content</td>
</tr>

The first row gets odd, the next even, and so on. By the time you render a table, your rows are nicely styled without any manual index checks.

Common Use Cases in Rails Views

Alternating Row Colors in Tables

The “hello world” of cycle. In admin dashboards, reports, or any tabular data, you can keep things readable without cluttering your view logic.

<% @users.each do |user| %>
  <tr class="<%= cycle("bg-white", "bg-gray-50") %>">
    <td><%= user.name %></td>
    <td><%= user.email %></td>
  </tr>
<% end %>

Looping Through a Set of Values

You’re not limited to two options. Pass in as many values as you like:

<%= cycle("red", "green", "blue") %>

Reusing Limited Data for Layout Testing

This is where cycle shines for frontend development 😍. When testing layouts, you don’t always have a large dataset handy. Instead of creating fake records, you can cycle a small collection to simulate more items:

<% 20.times do %>
  <div class="item">
    <%= cycle(*@products.map(&:name)) %>
  </div>
<% end %>

Now you can see how your design holds up with overflowing content, without seeding extra data.

A Note on Modern CSS

It’s worth mentioning that some of the classic uses of cycle can now be solved directly in CSS.

For example, alternating row colors doesn’t require Rails logic anymore:

tr:nth-child(even) {
  background: #f9fafb;
}

You can also style an element when it's an odd or even child using the odd and even variants on tailwindcss:

<table>
  <!-- ... -->
  <tbody>
    {#each people as person}
      <tr class="odd:bg-white even:bg-gray-50 dark:odd:bg-gray-900/50 dark:even:bg-gray-950">
        <td>{person.name}</td>
        <td>{person.title}</td>
        <td>{person.email}</td>
      </tr>
    {/each}
  </tbody>
</table>

Think of CSS and cycle as complementary tools — each with its sweet spot.

Going Beyond the Basics: More Creative Uses

Cycling Through Classes for UI Components

Need to highlight sections differently? Use cycle to rotate through predefined classes:

<section class="p-4 <%= cycle("bg-yellow-100", "bg-green-100", "bg-blue-100") %>">
  <%= content %>
</section>

Step Indicators or Timelines

If you’re building a progress tracker, cycle can handle repetitive markers:

<% 5.times do %>
  <div class="step">
    <span class="number"><%= cycle(1, 2, 3, 4, 5) %></span>
    <span class="arrow"><%= cycle('→', '⇒') %></span>
  </div>
<% end %>

Nested Collections

Even in nested loops, cycle can bring order. For example, rotating through categories while displaying posts:

<% @categories.each do |category| %>
  <h2><%= category.name %></h2>
  <% category.posts.each do |post| %>
    <div class="post <%= cycle("a", "b", "c", name: "post_cycle") %>">
      <%= post.title %>
    </div>
  <% end %>
<% end %>

Notice the name: option — it lets you keep different cycles independent from each other, which is especially handy in complex views.

Potential Pitfalls and Considerations

Like any helper, cycle isn’t always the right tool:

  • Complex conditions: If your logic depends on business rules (not just alternating), an explicit conditional might be clearer.
  • Multiple loops: Remember to use the name: option if you’re calling cycle inside different loops. Otherwise, they’ll step on each other and cause confusing results.
  • Debugging: Overusing cycle can make it harder to reason about why a particular element has a class — especially when mixing multiple cycles in a view.

Conclusion: Why cycle is a Hidden Gem

Rails has a knack for giving us small helpers that solve specific, recurring problems. cycle is one of those.

From alternating rows to UI patterns and even layout testing, it’s more versatile than it first appears. The next time you find yourself writing conditional view logic for repeating styles or testing layouts with too little data — reach for cycle.

It’s a small gem, but one that can keep your views both cleaner and smarter. Give it a try in your Rails app and see where it simplifies your templates.

References

Subscribe to get future articles via the RSS feed .