Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Railsの技: cycleメソッドでビューのループの「i%2==0」を避ける(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Railsの技: cycleメソッドでビューのループの「i%2==0」を避ける(翻訳)

ビューのレンダリングで、ループの回数をトラッキングする必要が生じることがあります(1行ごとに背景色を変える「ストライプテーブル」を作る場合など)。

<!-- @foods = ["apple", "orange", "banana"] -->

<% @foods.each do |food| %>
  <tr class="???">
    <td><%= food %></td>
  </tr>
<% end %>

皆さんも、CSSのoddeven子セレクタ1を使うか、以下のようにRubyのeach_with_indexメソッドで背景色を切り替えてみたことがおありでしょう。

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= i % 2 == 0 ? 'bg-gray-200' : 'bg-gray-100' %>">
    <td><%= food %></td>
  </tr>
<% end %>

以下のようにi.odd?i.even?で少々リファクタリングする手もあります。

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= i.even? ? 'bg-gray-200' : 'bg-gray-100' %>">
    <td><%= food %></td>
  </tr>
<% end %>

Railsには、こんなときに重宝するcycleヘルパーメソッドも用意されています。

使い方

cycleヘルパーは1個の配列を引数に取り、呼ばれるたびに配列の要素を順に返します。

上のコードは以下に置き換えられます。

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= cycle('bg-gray-200', 'bg-gray-100') %>">
    <td><%= food %></td>
  </tr>
<% end %>

cycleヘルパーにオプションを3つ以上渡すと、本当のありがたみが見えてきます。

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= cycle('bg-red-100', 'bg-orange-100', 'bg-yellow-100') %>">
    <td><%= food %></td>
  </tr>
<% end %>

cycleを手動でリセットする必要がある場合や、コード間で共有する必要がある場合は、オプションにname:キーを渡せます。

cycle("red", "white", "blue", name: "colors")
cycle("sm", "md", "lg", "xl", name: "sizes")

reset_cycle("colors")
reset_cycle("sizes")

cycleでは、to_sに応答するオブジェクトなら何でも使えます。

<% @items.each do |item| %>
  <div class="rotate-<%= cycle(0, 45, 90, 135, 180) %>">
    <%= item %>
  </div>
<% end %>

参考資料

関連記事

Railsの技: highlightヘルパーで検索結果を強調表示する(翻訳)



  1. CSS擬似クラス:nth-child()oddevenキーワードか、記事末尾のTailwindのodd-childやeven-childの指定を指していると思われます(おそらく後者)。 

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。