【Ruby on Rails】captureとscanを使ってHTMLの複雑な表示条件をシンプルに記述する

シェアする

この記事では、captureとscanの2つのメソッドを使用して、HTMLの複雑な表示条件をすっきりシンプルに記述する実装例をご紹介します。
深いネストや難解な条件式を避け、管理しやすいコードにするのがねらいです。

HTMLへの表示条件が複雑なケースの例

たとえば、会員機能のあるサイト内にお知らせ情報を表示したいとします。
更に、年齢や性別といった会員の属性によって表示したいお知らせ内容が異なり、

  • プレミアム会員にのみ表示するお知らせ
  • 女性会員にのみ表示するお知らせ
  • 30歳以上の女性会員にのみ表示するお知らせ
  • 都内在住の会員にのみ表示するお知らせ

の4種類のお知らせが存在します。
これだけなら、ひとつひとつの条件についてifで分岐して表示させれば良いですね。

しかし、会員がいずれの属性にも該当しない場合は、お知らせ情報の表示領域自体を非表示にしたいという要件が加わるとどうでしょう。

この場合、まずお知らせ情報を表示する条件のいずれか一つに合致するかどうかを判定し、その後で各お知らせの表示条件を判定する必要があります。
これ時点で非常に読みにくいコードになりそうですし、お知らせ情報や表示条件が増えたら修正も大変です。

captureとscanを使ってシンプルに記述する

captureメソッドを使用することで、出力内容を変数に保存することができます。
scanメソッドは、引数で指定した文字列にマッチする部分を取り出すことができます。

この2つのメソッドを使って、先の例の表示条件をシンプルに記述します。
考え方は以下の通りです。

  1. まずcaptureメソッド内で会員属性に合致するお知らせをすべて出力し、変数に格納する
  2. 1の変数に対してscanメソッドを使用し、出力されたお知らせ情報の件数を判定する

それでは実装例をみてみましょう。

<% # captureでお知らせ情報の出力内容を変数に格納する %>
<% info = capture do %>
  <div class="info">
    <span class="info-index">サイトからのお知らせ</span>
    
    <% # 会員属性ごとにお知らせ情報を出力する %>
    <% if member.premium? %> 
      <a href="url">プレミアム会員用のお知らせ</a>
    <% end %>

    <% if member.female? %> 
      <a href="url">女性会員用のお知らせ</a>
      <% if member.age >= 30 %> 
        <a href="url">30歳以上の女性会員用のお知らせ</a>
      <% end %>
    <% end %>

    <% if member.prefecture == "東京" %> 
      <a href="url">都内会員用のお知らせ</a>
    <% end %>
  </div>
<% end %>

<% # いずれかの会員属性にマッチする場合のみお知らせ情報を表示する %>
<% if info.scan("</a>").count > 0 %>info<% end %>

いかがでしょうか。
これなら、お知らせ情報や表示条件が追加されても簡単に修正できそうですね。
ポイントは、aタグの数によって出力されたお知らせの件数を判定していることです。

このようにcaptureとscanの合わせ技で、出力されたhtmlの内容をもとに処理を行うことができます。
ぜひご活用ください。

シェアする

フォローする