【Rails】Action View(ビュー)の書き方《基本篇》

2021年4月16日 13:16

はじめに

ActionView(または単にビュー)は、クライアントに表示するWebページを構築します。モデルのデータをコントローラーから受け取り、それを適切な形で画面上に配置します。ビューでは、ヘッダーやフッターなどの共通部分を部品化してテンプレートに埋め込む機能や、画像などのアセットファイルを呼び出すアセットタグヘルパーを使うことができます。

本記事では、ActionView(ビュー)の使い方をまとめています。

ビューの基本

ビューはapp/view/ディレクトリ配下に作成します。コントローラー名のディレクトリを作成し、その中に各画面のテンプレートを作成していきます。

ビューの作成

ビューを作成するには以下のコマンドを実行します。

$ rails generate controller Users index

コントローラーを作成するコマンドの引数にアクションを指定すると一緒に対応するビューも作成されます。コントローラーは作成済みでビューを追加したい場合は手動で作ってしまって問題ありません。

一応、ビューだけを作成するコマンドもあります。

$ rails generate erb:scaffold User name

scaffoldはコントローラー、モデル、マイグレーション、ビュー、ルーティングを一度に作成するコマンドですが、erb:scaffoldはそのうちのビューだけを作成します。scaffoldはモデル名を指定するので単数形、その後にアクションではなくフィールド名を指定します。

作成されるビューには、最初からモデルのデータをコントローラーから受け取って表示する基本的なタグなどが記述されています。当然、別途コントローラーやモデルを作成しないと動作しないのでご注意ください。

ビューの削除

ビューを削除するには以下のいずれかのコマンドを実行します。一番上と真ん中のコマンドはビュー以外も削除されます。ビューだけを削除したいなら一番下のコマンドか手動で削除します。

$ rails destroy controller Users
$ rails destroy scaffold User
$ rails destroy erb:scaffold User

ビューの書き方

ビューの構成

ビューは、レイアウト、テンプレート、パーシャルの3つに分類されます。最も基本となるのがレイアウトで、その中に画面毎に異なるテンプレートを組み込み、テンプレートの共通部分はパーシャルとして部品化します。

レイアウト

レイアウトはapp/views/layouts/ディレクトリ配下に作成します。Railsは、現在のコントローラー名と同じ名前のレイアウトがあればそれを使用し、なければapplication.html.erbを使用します。例えば、UsersControllerからビューをレンダリングする際、users.html.erbというレイアウトがあればそれを使用します。

レイアウトではyieldcontent_forが使えます。以下は簡単なよくあるレイアウトの例です。

<!DOCTYPE html>
<html>
  <head>
    <title><%= yield :title %></title>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

このようなレイアウトに埋め込まれるテンプレートが以下のようになっているとします。

<% content_for :title do %>
  ユーザー一覧
<% end %>

<h1>ユーザー一覧</h1>

名前を指定していないyieldはテンプレートの内容をそのままレイアウトに組み込みます。一方、名前を指定しているyieldは、テンプレートに含まれるcontent_forブロックに囲まれた内容のみをレイアウトに組み込みます。

上記の例では、名前を指定していないyieldには見出しタグのみが組み込まれ、titleという名前を指定しているyieldには「ユーザー一覧」という文字列がヘッダーのタイトルに組み込まれます。なお、content_forブロックの内容が一行なら代わりにprovideを使うこともできます。

<% provide "ユーザー一覧" %>

<h1>ユーザー一覧</h1>

名前を指定しているyieldはレイアウト内に何種類でも記述することができます。名前を指定していないyieldも何回も記述することができますが、記述した分だけテンプレートが組み込まれることになるのでご注意ください(同じ内容がyieldの数だけ組み込まれる)。

テンプレート

テンプレートはapp/views/ディレクトリ配下の各コントローラー名のディレクトリ配下に作成します。一覧画面、詳細画面、作成画面、編集画面といった画面毎にひとつのテンプレートを作成します。

テンプレートはERB (Embedded Ruby) テンプレートシステムを使って記述することが多いです。ERBファイル(拡張子:.html.erb)では、<% %>タグや<%= %>タグの中にRubyコードを記述することができます。<% %>タグの中のRubyコードは処理結果を出力しないので、条件文や繰り返し、変数の宣言といったRubyコードを記述します。<%= %>タグの中のRubyコードは処理結果を出力します。

すべてのユーザー名を表示するコードの例は以下の通りです。

<ul>
  <% @users.each do |user| %>
    <li><%= user.name %></li>
  <% end %>
</ul>

パーシャル

パーシャルは、テンプレートに含まれる内容のうち、ヘッダーやフッター、サイドバーといった各画面で共通している部分を抜き出し、独立したファイルとして扱います。部品化したパーシャルはテンプレートの好きな部分に組み込むことができます。

パーシャルはapp/views/ディレクトリ配下の各コントローラー名のディレクトリ配下に作成します。すべてのコントローラーで共通して使用するパーシャルはapp/views/shared/ディレクトリ配下に作成しても構いません。パーシャルのファイル名は先頭に_(アンダースコア)をつけます(_header.html.erbなど)。

以下は記事を新規投稿するテンプレート(app/views/articles/new.html.erb)の例です。

<%= render "shared/header" %>

<h1>新規投稿フォーム</h1>
<%= render "form" %>

<%= render "shared/footer" %>

renderを使ってテンプレートにパーシャルを組み込みます。指定するパーシャルの名前は先頭の_(アンダースコア)と拡張子を省略することができます。app/views/ディレクトリから見たパスを指定する必要がありますが、パーシャルがテンプレートと同じディレクトリに存在する場合はディレクトリ名を省略することができます(formパーシャルはapp/views/articles/_form.html.erbなのでディレクトリ名は省略できる)。

コントローラーからテンプレートに渡された変数は組み込まれたパーシャルでも使用することができます。

パーシャルに別のパーシャルを組み込むこともできます(パーシャルのネスト)。

ヘルパーメソッドの使用

ビューでは組み込みの様々なヘルパーメソッドが使用できます。ここでは、よく使うヘルパーメソッドを中心に紹介します。すべてのヘルパーメソッドを確認したい場合は以下を参照してください。

link_toはルーティングの<a></a>タグを生成します。おそらく最もよく使うヘルパーメソッドではないかと思います。第1引数はリンクする文字列、第2引数はルーティングでここまでは必須です。第3引数以降はclassidなどのオプションを指定します。

<%= link_to article.title, article_path(article.id) %>

以下のようにブロックで使うこともできます。

<%= link_to article_path(article.id) do %>
  <div class="box">
    <%= article.title %>
  </div>
<% end %>

以下はAjax通信で記事を削除するlink_toの例です。

<%= link_to '削除', article_path(article.id), method: :delete, remote: true, data { confirm: '本当に削除しますか?' } %>

アンカーリンク(ページ内リンク)は以下のように記述します。

# 同じページのアンカーリンク
<%= link_to '使い方', { anchor: 'how_to_use' } %>

# 違うページのアンカーリンク
<%= link_to '使い方', article_path(article.id, anchor: 'how_to_use') %>

image_tag / image_pack_tag

image_tagは画像アセットの<img />タグを生成します。第1引数はapp/assets/images/ディレクトリ配下の画像ファイルを指定します。第2引数以降は必要に応じてオプションを指定します。

<%= image_tag 'icon.png' %>

画像ファイルはアセットパイプラインによってコンパイルされ、ファイル名の末尾に一意な識別子が付加されます。image_tagはコンパイル後のファイル名を解決して<img />タグを生成します。

画像ファイルをWebpackerで管理している場合はimage_pack_tagを使います。

<%= image_pack_tag 'icon.png' %>

その他のアセットタグヘルパー

CSSやJavaScriptを読み込むアセットタグヘルパーが使えます。以下の例ではapp/assets/ディレクトリ配下のapplication.cssapplication.jsを読み込んでいます。読み込むファイルは,(カンマ)で区切って複数指定することができます。

<head>
  <%= stylesheet_link_tag 'application' %>
  <%= javascript_include_tag 'application' %>
</head>

CDNを指定することもできます。

<head>
  <%= stylesheet_link_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css' %>
  <%= javascript_include_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js' %>
</head>

Webpackerで管理している場合は以下のように記述します。

<head>
  <%= stylesheet_pack_tag 'application' %>
  <%= javascript_pack_tag 'application' %>
</head>

まとめ

ビューはユーザーが直接目にする部分だけに最も重要な機能であるとも言えます。ユーザーフレンドリーなデザインを心がけることはもちろんですが、レイアウトやテンプレート、パーシャルをうまく使ってDRY (Don't Rpeat Yourself) なコードにすることも同じくらい大切です。

本記事を参考にして、ActionView(ビュー)の使い方について覚えていただければと思います。

関連記事

【Rails】Railsアプリのデバッグ《マルチデバイス篇》
# はじめに 近年のWebアプリはレスポンシブ対応が当たり前になっています。最低でもPCとスマートフォンに対応したデザイン、ときにはその中間のタブレットに対応したデザインなんかも作成する必要があります。 Webアプリの開発はPCを使って行う [...]
2021年5月23日 13:02
【Rails】Railsアプリのデバッグ《Better Errors篇》
# はじめに Railsアプリの開発中になんらかのエラーが発生すると、デフォルトでは以下のような画面が表示されます(画像をクリックすると拡大します)。 <a class="gallery" data-group="gallery" href [...]
2021年5月22日 19:42
【Rails】Railsアプリのデバッグ《byebug篇》
# はじめに Ruby on Railsに限りませんが、アプリの開発中にはエラーは付き物です。なにかしらのエラーが発生したときに、エラーの原因を特定しエラー箇所を修正することをデバッグと言います。Railsではデバッグの手助けとなる機能があらかじ [...]
2021年5月22日 15:30
【Rails】レンダリング(renderメソッド)でアンカー指定を行う
# はじめに 通常、Railsでアンカー付きのリクエストを発生させるには`redirect_to`を使います。 ```rb redirect_to root_path(anchor: 'target') ``` では、`rende [...]
2021年5月20日 10:47
【Rails】Bundler 2.2.x以降は開発者が適切なプラットフォームを追加する必要がある
# 事象 昔作ったRailsアプリを久しぶりに修正しデプロイしようとしたところ、以下のエラーが出力されました。 ```bash # 実行コマンド Running $HOME/.rbenv/bin/rbenv exec bundle ch [...]
2021年5月18日 16:18