すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

データ表示画面の作成(Read)

この記事で出来るようになること

はじめに

概要

この記事では、Ruby on Railsでデータの表示方法を学びます。データベースから取得した情報をユーザーに表示することは、Webアプリケーションにおいて基本的かつ重要な機能です。社員一覧画面と社員詳細画面の作成を通じて、Railsでどのようにデータを画面に表示するかを学んでいきましょう。

目標

この章の目標
  • 社員一覧画面と社員詳細画面の作成手順を把握し、実装できるようになる。
  • データを画面に表示するためのRailsの基本原則を理解する。
  • Webブラウザを通じてデータをユーザーに提示する一連の流れについて学ぶ。
この章で完成するもの

この章では、社員の情報を一覧で表示し、各社員の「詳細情報」リンクをクリックすることで、その社員の詳細情報を表示する画面の完成を目指します。

必要な前提条件・事前準備

事前準備として、デバッグツール「Pry-Rails」の導入を行います。実装を進める上で、Pry-Railsを活用して動作確認を行います。

以下の手順で「Pry-Rails」をインストールしてください。

「Pry-Rails」の導入

Pry-Railsとは、Ruby on Railsの開発環境において、標準のコンソールを強化するためのGemです。Pryをベースにしており、Rails特有の機能へのアクセスや、デバッグ時の操作性を向上させます。

gemを追加しよう

まずは、「employee_management」直下にある「Gemfile」をダブルクリックして、テキストエディタを開いてください。

Gemfileをダブルクリック

「Gemfile」に以下のハイライトされた1行を追加しましょう。

Gemfile | pry-railsを追加する
1
2
3
4
5
6
7
8
9
10
11
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# ... [中略] ...

group :development, :test do
  gem 'byebug', '11.1.3'
gem 'pry-rails', '0.3.9' # この行を追加
end # ... [後略] ...

そして、Gemfileに追加したGemをbundle installコマンドでインストールしましょう。カレントディレクトリが「employee_management」になっていることを確認し、ターミナルで以下のコマンドを実行します。

ターミナル(~/environment/employee_management) | Gemをインストールする
1
bundle install

インストールが完了したら、rails console(またはrails c)を実行すると、Pryベースのコンソールが起動します。Pryはコマンドライン上で動作し、コードを一行ずつ入力して直接実行することができます。

アプリケーションの動作をリアルタイムで探索したり、特定のコードがどのように動作するかを試したりすることが可能になるよ!

ぴかわかさん
ぴっかちゃん

自由にコードを試して学ぶことができるんだね!

Pry-Railsを導入する前は、プロンプトが2.7.5:001と表示されていました。

Pry-Rails導入後は、プロンプトが[1] pry(main)>に変更されます。

Pry-Railsの具体的な使用方法については、実際に使用する箇所で解説します。これでPry-Railsの導入作業は完了です。

1. 社員一覧画面を実装

まずは、データベース内の全社員情報を表形式で表示する社員一覧画面の実装に取り組みます。この画面の主な目的は、WebブラウザからGET /employeesというリクエストを送信した際に、社員情報を一覧形式で表示することです。

以下の画像は、この社員一覧画面の実装を終えたときにできあがる画面です。

それでは、社員一覧画面の実装に取り組みましょう!

ぴかわかさん

一覧表示のルート確認

Webブラウザからリクエストが送信されたとき、最初に処理されるのはルーティングです。

ルーティングは、すでにRESTfulルーティングに沿った設計で設定されています。そのため、社員の一覧を表示する目的でGET /employeesのリクエストが送信されると、employeesコントローラのindexアクションが実行されるようになっています。

ルーティングが適切に設定されているかを確認しましょう

config/routes.rbファイルに社員一覧を表示するためのルートが以下のように適切に設定されているか確認してください。

この設定により、employeesコントローラのindexアクションに対応付けられます。

ぴっかちゃん

RESTfulルーティングに対応するコントローラのアクションも「7つのアクション」で設定済みだったね!

コントローラの作成と設定は飛ばして、次はビューを作成するよ!

ぴかわかさん

一覧表示ビューの作成

以前学んだように、アクション名と同名のビューファイルがデフォルトで使用されます。employeesコントローラのindexアクションに対応するindex.html.erbファイルは、すでに作成済みです。

index.html.erbには、以下の内容が記述されています。このビューを変更し、社員の一覧をユーザーに表示できるようにします。

app/views/employees/index.html.erb
1
2
<h2>社員情報一覧</h2>
<p><%= @text %></p>
ダミーデータで社員情報を表示できるように変更しましょう

社員情報を管理するデータベース内のemployeesテーブルには、以下の画像に示されるようなデータが既に挿入されています。

最終的にはデータベースからデータを取り出し、ビューで表示する予定ですが、まずは理解を深めるためにデータベースを使用せずダミーデータで社員情報を表示させます。

index.html.erbファイルを以下のハイライトされた箇所の通りに変更し、データベースからデータを取得する代わりにビューに直接ダミーデータを記述しましょう。

app/views/employees/index.html.erb | 変更前
1
2
<h2>社員情報一覧</h2>
<p><%= @text %></p>
app/views/employees/index.html.erb | 変更後
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<h2>社員情報一覧</h2>

<table>
<!-- テーブルのヘッダー -->
<thead>
<tr>
<th>名前</th>
<th>生年月日</th>
</tr>
</thead>
<!-- テーブルのボディ -->
<tbody>
<tr>
<td>田中太郎</td>
<td>1980-10-22</td>
</tr>
<tr>
<td>山田花子</td>
<td>1983-08-20</td>
</tr>
<tr>
<td>高橋一朗</td>
<td>1986-06-16</td>
</tr>
<tr>
<td>伊藤晴子</td>
<td>1987-10-01</td>
</tr>
<tr>
<td>鈴木二郎</td>
<td>1990-01-17</td>
</tr>
<tr>
<td>山口冬子</td>
<td>1993-05-12</td>
</tr>
</tbody>
</table>

次に、ビューにスタイルを適用させます。

layout.scssファイルに以下のハイライトされたコードを追加しましょう。このコードにより、テーブルのマージン、背景色、パディングなどのスタイリングが設定されます。

app/assets/stylesheets/layout.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
body {
  display: flex;
  flex-direction: column;
}

// ... [中略] ...

.content-wrapper h2 {
  font-size: 26px;
}

table {
margin: 25px 0;
}
table th {
background-color: #ffd099;
padding: 10px 20px;
}
table td {
background-color: #fff2e2;
padding: 10px 20px;
}
.footer { margin-top: 70px; padding: 6px; background: #525fe1; } // ... [後略] ...

最後に、WebブラウザでURLの末尾に/employeesを追加し、アクセスしてみましょう。このとき、rails sでサーバーを起動させることを忘れないでください。

アクセスすると、以下の画像のように社員情報を表示する画面が現れ、先ほど追加したスタイルが適用されていることを確認できます。

ここではデータベースからのデータ取得を行わず、ビューに直接ダミーデータを記述しました。次に、データベースのテーブルからデータを取得し、社員情報を表示する方法について学びます。

ぴかわかさん

indexアクションの実装

次に、データベースから全社員の情報を取得し、それをビューに渡すためにemployeesコントローラのindexアクションを実装します。

indexアクションを実装しましょう

indexアクション内に、以下のハイライトされた1行を追加しましょう。

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
class EmployeesController < ApplicationController
  def index
    # 社員の一覧を取得する処理
@employees = Employee.all
end # ... [後略] ... end

レコードの取得には、ActiveRecordが提供するallメソッドを利用します。このallメソッドは、モデルに対応するテーブルのすべてのレコードを取得する機能を持っています。

そのため、indexアクション内のEmployee.allでは、データベースのemployeesテーブルから全社員の情報を取得します。

その後、取得した社員情報を@employees変数に代入することで、ビューからのアクセスを可能にします。レコードが複数存在するため、インスタンス変数は複数形の@employeesとしています。

コントローラのアクションからビューファイルへデータを渡す際には、このようなインスタンス変数が利用されます。

indexアクションに対応するビューを修正しましょう

現段階ではダミーデータをビューファイルに直接記述していますが、これをコントローラのアクションから渡される@employeesインスタンス変数を利用して書き換えましょう。

index.html.erbファイルを以下のように書き換えてください。

app/views/employees/index.html.erb | 変更前
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<h2>社員情報一覧</h2>

<table>
  <!-- テーブルのヘッダー -->
  <thead>
    <tr>
      <th>名前</th>
      <th>生年月日</th>
    </tr>
  </thead>
  <!-- テーブルのボディ -->
  <tbody>
<tr>
<td>田中太郎</td>
<td>1980-10-22</td>
</tr>
<tr>
<td>山田花子</td>
<td>1983-08-20</td>
</tr>
<tr>
<td>高橋一朗</td>
<td>1986-06-16</td>
</tr>
<tr>
<td>伊藤晴子</td>
<td>1987-10-01</td>
</tr>
<tr>
<td>鈴木二郎</td>
<td>1990-01-17</td>
</tr>
<tr>
<td>山口冬子</td>
<td>1993-05-12</td>
</tr>
</tbody> </table>
app/views/employees/index.html.erb | 変更後
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<h2>社員情報一覧</h2>

<table>
  <!-- テーブルのヘッダー -->
  <thead>
    <tr>
      <th>名前</th>
      <th>生年月日</th>
    </tr>
  </thead>
  <!-- テーブルのボディ -->
  <tbody>
<% @employees.each do |employee| %>
<tr>
<td><%= employee.name %></td>
<td><%= employee.birthday %></td>
</tr>
<% end %>
</tbody> </table>

@employeesには全社員情報が代入されており、ビュー内でeachメソッドを用いてループ処理を行い、それぞれの社員のデータを表示するために使用します。この辺の説明は、あとでコードの挙動を調べながら進めていきます。

Webブラウザで表示を確認しましょう

WebブラウザでURLの末尾に/employeesを追加し、アクセスしてみましょう。このとき、rails sでサーバーを起動させることを忘れないでください。

アクセスすると、以下の画像のように社員情報を表示する画面が現れます。見た目は先ほどと変わりませんが、今回はデータベースから取得したデータを表示しています。

ビュー内では、以下のように@employeesを利用し、ループ処理を行い、それぞれの社員のデータを表示する処理を行っていましたね。

app/views/employees/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
<h2>社員情報一覧</h2>
  <!-- 中略 -->
  <tbody>
<% @employees.each do |employee| %>
<tr>
<td><%= employee.name %></td>
<td><%= employee.birthday %></td>
</tr>
<% end %>
</tbody> </table>

デベロッパーツールで上記の表示結果のHTML構造を確認すると、生成されたHTMLが期待通りに各社員の情報を正確に表していることが確認できます。

具体的には、<tr>タグ内に社員の名前と生年月日が<td>タグで囲まれて配置され、@employees内の各要素に対応する行がしっかりとビューに表示されています。ビューが動的にデータベースから取得した情報を反映していることが視覚的にも明確になります。

ぴっかちゃん

index.html.erbファイル内に書いたコードで画面がさっきみたいに表示されているのがまだよく分からないなぁ...。

この辺は、次でPry-Railsを使ってプログラムがどのように実行されるかを一歩一歩追って理解を深めることができるから、安心してね!

ぴかわかさん

Pry-Railsで社員情報の動作確認

Pry-Railsを利用すると、デバッグ(プログラムやシステムに存在するバグ、つまりエラーや問題を特定し、修正するプロセス)を行う以外にも、アプリケーションの動作をリアルタイムで探索したり、特定のコードの挙動を詳しく調べる際に役立ちます。

使い方は簡単で、デバッグやコードの挙動を理解したい箇所binding.pryというブレークポイント(プログラムの実行を特定の地点で一時的に停止させるためのマーカーまたは指示)を挿入します。

例 | コードにbinding.pryを挿入する
1
2
3
4
5
def some_method
  var = '何かの値'
binding.pry # ここで実行が停止し、デバッグセッションが開始されます。
# その他の処理... end

その後、プログラムを通常どおりに実行します。実行がbinding.pryに到達すると、コンソールにPryプロンプトが表示されます。ここでコードの実行をステップごとに進めたり、プログラムの状態を詳しく調べたりすることができます。

今回は、index.html.erbファイル内のコードの挙動の理解するために利用します。

app/views/employees/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
<h2>社員情報一覧</h2>
  <!-- 中略 -->
  <tbody>
    <% @employees.each do |employee| %>
      <tr>
        <td><%= employee.name %></td>
        <td><%= employee.birthday %></td>
      </tr>
    <% end %>
  </tbody>
</table>

Pry-Railsを使って挙動を理解したい箇所は、2箇所あります。

まずは@employeesの中身です。コントローラのindexアクションでデータベースから取得したデータがビューに渡っているかを確認します。2箇所目はループ処理の中です。employeeには何が入っているのか、employee.nameemployee.birthdayでどのような処理が行われているのかを調べます。

コードにブレークポイントbinding.pryを挿入しましょう

index.html.erbファイルにbinding.pryを挿入します。html.erbファイルでは、<% %>を使ってbinding.pryを囲みます。

以下の2箇所に<% binding.pry %>を挿入しましょう。

app/views/employees/index.html.erb | binding.pryを挿入する
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<h2>社員情報一覧</h2>

<table>
  <!-- テーブルのヘッダー -->
  <thead>
    <tr>
      <th>名前</th>
      <th>生年月日</th>
    </tr>
  </thead>
  <!-- テーブルのボディ -->
  <tbody>
<% binding.pry %>
<% @employees.each do |employee| %>
<% binding.pry %>
<tr> <td><%= employee.name %></td> <td><%= employee.birthday %></td> </tr> <% end %> </tbody> </table>

<%= %>ではなく<% %>binding.pryを囲むことも重要だよ。

ぴかわかさん
ぴっかちゃん

たしか<%= %>だと、Rubyのコードの実行結果をHTMLに出力しちゃうんだよね!

プログラムを通常どおりに実行しましょう

コードにbinding.pryを挿入した後、プログラムを通常通りに実行します。すでにWebブラウザ上で社員一覧画面を表示している方は、ページを再読み込みしてください。まだ表示していない方は、rails sでサーバーを起動し、WebブラウザのURLの末尾に/employeesを追加してアクセスしてみましょう。

すると、以下のようにデフォルトの起動画面(または社員一覧画面)では、読み込み中の状態が続いているように見えます。

この状態は、サーバー側の処理がbinding.pryに到達してコード内で実行された結果、プログラムがその地点で一時的に実行を停止しているため発生します。

このとき、rails sで起動したサーバーのコンソールを確認すると、以下のようにPryプロンプトが表示されていることがわかります。さらにプログラムが一時停止している正確な箇所も把握できます。

[1] pry(#<#<Class:xxxx>>)>の数字は一致している必要はありません。

このPryコンソールで、プログラムの状態を確認したり、コードのステップを一つずつ進めたりすることができます。

ぴかわかさん
Pryコンソールで@employeesの値を確認しましょう。

最初のbinding.pryでプログラムが一時停止している箇所では、コントローラのindexアクションでデータベースから取得したデータがビューに渡されているかどうかを確認するため、@employeesの中身をチェックします。

Pryコンソールでは、以下のように13行目でプログラムが一時停止していることを確認してください。[1] pry(#<#Class:xxxxx)>のプロンプトに入力していきます。

上記のプログラムが一時停止している箇所は、ビューでは以下の箇所に対応します。

app/views/employees/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h2>社員情報一覧</h2>

<table>
  <!-- テーブルのヘッダー -->
  <thead>
    <tr>
      <th>名前</th>
      <th>生年月日</th>
    </tr>
  </thead>
  <!-- テーブルのボディ -->
  <tbody>
<% binding.pry %> <!-- ここで処理が一時停止しています -->
<% @employees.each do |employee| %> <!-- [後略] -->

コントローラのindexアクションから渡された「@employees」はindex.html.erbファイル内の任意の場所で利用することができます。上記のブレークポイントで@employeesの値を確認することにより、コードの実行時にどのようなデータがビューに渡されているかを理解することができます。

それでは、以下のPryコンソールで@employeesを入力し、returnキーもしくはEnterキーを押してください。

すると、以下のように@employeesに代入されている値が表示されます。

上記の値は、employeesコントローラのindexアクション内でEmployee.allを実行した結果で、データベースのemployeesテーブルから取得した全社員の情報です。

これらのデータは@employeesに配列に似た構造(ActiveRecord::Relationオブジェクトのコレクション)で代入されています。

この@employees配列のように扱うことができるので、eachメソッドなどを使って反復処理を行ったり、特定の要素にアクセスしたりすることが可能です。

さらに、各要素はEmployeeクラスのインスタンスであり、これはデータベースのemployeesテーブルの各行をRubyオブジェクトとして表現しています。つまり、このコレクションに含まれる各要素は、データベース内の一行のデータに対応しており、その属性(例えば名前や生年月日など)にプログラムからアクセスできます。

ぴっかちゃん

少しわかってきたよ!このデータを配列のように扱えるから、ビューでは@employeesにeachメソッドを使って、各要素(Employeeクラスのインスタンス)の名前などにアクセスしているんだね!

その通りだよ!@employeesはデータベースから取得した全社員の情報を格納していて、ビューでは、この@employeesをeachメソッドで一つずつループして、各社員の情報を個別に表示しているんだよ。次は、この辺をさらに深く理解できるように手を動かして確認するよ!

ぴかわかさん
次のブレークポイントに移動しましょう

Pryのプロンプトが[2] pry(#<#<Class:xxx>>)>のような形式で表示されておらず、(END):が表示されている場合は、以下の動画のように:qと入力して、@employeesの値が表示から抜け出しましょう。

抜け出すと、[2] pry(#<#<Class:xxx>>)>が表示されます。

次のブレークポイントまで進めるために、Pryコンソールでexitを実行しましょう。

実行後、Pryコンソールでは、以下のように13行目ではなく、次のブレークポイントである15行目の<% binding.pry %>でプログラムが一時停止します。

ループ処理の流れを画像とコードで一旦整理しましょう

2箇所目のブレークポイントは、ループ処理の中です。

先ほど確認したように、@employeesは配列のようなものであり、具体的にはActiveRecord::Relationオブジェクトのコレクションです。このコレクションの各要素にはEmployeeクラスのインスタンスが代入されています。

この@employeeseachメソッドとブロック(doend)を使用することで、要素ごと(Employeeクラスのインスタンスごと)の繰り返し処理が可能になります。@employeesの各要素は順番に取り出され、ブロック変数employeeに一つずつ代入されます。そして、ブロック内で各要素に対する処理が行われます。

app/views/employees/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h2>社員情報一覧</h2>

<table>
  <!-- [中略] -->
  <tbody>
    <% binding.pry %>
<% @employees.each do |employee| %><!-- 要素ごとに繰り返し処理を行う -->
<% binding.pry %><!-- ここで処理が一時停止しています -->
<tr>
<td><%= employee.name %></td>
<td><%= employee.birthday %></td>
</tr>
<% end %>
</tbody> </table>

つまり、最初のループでは、@employees内の最初の要素であるEmployeeクラスのインスタンス(田中太郎さんの社員情報)がブロック変数employeeに代入されます。

Pryコンソールでemployeeの値を確認してみましょう

ブレークポイントでemployeeの値を確認することにより、@employees内の最初の要素がどのように渡されているか理解することができます。

それでは、以下のPryコンソールのプロンプトでemployeeを実行しましょう。

Pryコンソールでemployeeを実行すると、以下のように最初の要素であるEmployeeクラスのインスタンス(田中太郎さんの社員情報)が代入されていることがわかります。

Pryコンソールでemployee.nameやemployee.birthdayの値 を確認してみましょう

Pryコンソールでemployee.nameemployee.birthdayを実行してみましょう。

実行すると、以下のようにEmployeeクラスのインスタンス(田中太郎さんの社員情報)の属性である名前と生年月日の値にアクセスできることが確認できます。

つまり、ビュー内での<td><%= employee.name %></td>では、<td>田中太郎</td>という値が生成されていることになります。生年月日についても同様に、田中さんのemployee.birthdayの値が適切に表示されます。

これらのデータは、以下の画像のように社員情報一覧画面で表の1行目を生成するのに使用されていることが確認できます。また、ビューではRailsのデフォルト設定などよって日付形式が適用されるため、生年月日はPryコンソールで確認したWed, 22 Oct 1980ではなく、1980-10-22で表示されます。

最初のループ処理の流れを整理しましょう

次のループをPryコンソールで確認する前に、まずは処理の流れを整理しましょう。

eachメソッドは@employeesの最初の要素(田中さんの情報を持つインスタンス)を取り出し、ブロック内の処理を上から順に実行します。

そして、処理が<% end %>に到達すると、eachメソッドは@employeesの次の要素(山田さんの情報を持つインスタンス)を取り出し、新たなループを開始し、ブロック内の処理を再び上から実行します。

このプロセスは@employeesの全ての要素が処理されるまで繰り返されます。つまり、以下のハイライトされるコードが全ての要素に対して実行されることになります。

app/views/employees/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h2>社員情報一覧</h2>

<table>
  <!-- [中略] -->
  <tbody>
    <% binding.pry %>
    <% @employees.each do |employee| %>
<% binding.pry %>
<tr>
<td><%= employee.name %></td>
<td><%= employee.birthday %></td>
</tr>
<% end %> </tbody> </table>
次のループに進みましょう

現在のPryコンソールは、最初のループ(山田さんの情報を持つインスタンスの処理)のブレークポイントにあります。次のループでのemployeeなどを確認するには、最初のループを終えるためにexitを実行する必要があります。

Pryコンソールでexitを実行してみましょう。すると、プログラムは次のループに進み、再び15行目のbinding.pryによって一時停止します。

次のループでemployeeを実行してみましょう

次に、Pryコンソールでemployeeを実行してみましょう。これにより、@employeesの次の要素(例として山田さんの情報を持つインスタンス)がブロック変数employeeに代入されていることが確認できます。

この結果から、上記のループでemployee.nameemployee.birthdayを使用すると、山田さんの情報を持つインスタンスの属性にアクセスすることがわかります。

ビュー内での<td><%= employee.name %></td>では、以下のように<td>山田花子</td>というHTMLが生成されています。生年月日についても同様に、山田さんのemployee.birthdayの値が適切に表示されます。

ぴっかちゃん

<tr><td>eachメソッド内にあると、これらのタグも繰り返し生成されるんだね。

ERBファイルのおかげでRubyのコードをHTML内で使えるから、データを繰り返し表示するだけじゃなく、<tr><td>のようなHTMLタグも要素の数だけ自動的に繰り返し生成できるよ。

ぴかわかさん
ぴっかちゃん

繰り返されるコードを短くして、すっきり書けるね!

全てのループから抜け出そう

Pryコンソールでexitを実行すると、現在のループを終了し、プログラムは次のループに進み、再び15行目のbinding.pryで一時停止します。これが各要素について繰り返されます。全てのループから抜け出し、Pryセッションを終了するためには、!!!コマンドを実行しましょう。

!!!を実行すると、以下のようにPryのプロンプトがコンソールから消えます。

binding.pryを削除しましょう

この状態で、ビューファイル内のbinding.pryを削除しましょう。

app/views/employees/index.html.erb | binding.pryを削除する
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<h2>社員情報一覧</h2>

<table>
  <!-- テーブルのヘッダー -->
  <thead>
    <tr>
      <th>名前</th>
      <th>生年月日</th>
    </tr>
  </thead>
  <!-- テーブルのボディ -->
  <tbody>
<% binding.pry %> <!-- 削除する -->
<% @employees.each do |employee| %>
<% binding.pry %> <!-- 削除する -->
<tr> <td><%= employee.name %></td> <td><%= employee.birthday %></td> </tr> <% end %> </tbody> </table>
Webブラウザを再読み込みしましょう

binding.pryを削除した後は、Webブラウザを再読み込みしましょう。

すると、以下の画像のように社員情報を表示する画面が表示されます。

ブレークポイントで確認していたPryコンソールも、サーバーのログ表示に戻ります。

さて、Pry-Railsを使った社員情報一覧の挙動確認はこれでおしまいだね!今回のように、今後もコードを一歩ずつ確かめながら進めることがあるから、Pryの使い方はしっかり覚えておいてね。

ぴかわかさん
ぴっかちゃん

index.html.erb@employeeseachメソッドで繰り返し処理するコードが最初は難しく感じたけど、Pryで一つ一つ確認することでよく理解できたよ!

2. 社員詳細画面を実装

次に、各社員の詳細な情報を見ることができる「社員詳細画面」の実装に進みます。この画面の主な目的は、一覧画面の各社員に追加される「詳細」リンクをクリックした際に、特定の社員の情報を表示することです。

以下の画像は、この社員詳細画面の実装を終えたときにできあがる画面の例です。

それでは、社員詳細画面の実装に取り組みましょう!

ぴかわかさん

詳細表示のルート確認

社員の詳細情報を表示するには、WebブラウザからGET /employees/:idという形式のリクエストを送信します。このリクエストは、employeesコントローラのshowアクションで処理されます。

RESTfulな設計原則に従って設定されたルーティングでは、特定の社員の詳細情報へ簡単にアクセスできる構造が整っています。具体的に見てみましょう。

以下は、設定済みのroutes.rbファイルの一部です。ここでは、employeesコントローラのshowアクションに対応付けされるルートが定義されています。

config/routes.rb
1
2
3
4
5
6
7
8
Rails.application.routes.draw do
  # ... [その他のルート設定] ...

  # 特定の社員の詳細を表示するためのルート
get 'employees/:id', to: 'employees#show'
# ... [その他のルート設定] ... end

routes.rbファイルで定義される:idはプレースホルダーとして機能します。これは、実際のリクエストが行われたとき、具体的な値に置き換わる部分です。

社員の詳細表示のルートget 'employees/:id'では、Webブラウザからのリクエストで/employees/に続く任意の値(数字や文字列):idに置き換わります。

例えば、リクエストが/employees/3の場合、:id3に、/employees/42の場合、:id42にそれぞれ置き換わります。

このように:idなどのプレースホルダを利用することで、get 'employees/:id'のような一つのルーティング設定で、/employees/3/employees/42など、さまざまなリクエストパスに対応できます。これにより、各リクエストに対して個別のルーティングを設定する必要がなくなり、コードがシンプルで柔軟性の高いものとなります。

ぴっかちゃん

一つの設定で色んなリクエストパスに対応できるなんて、プレースホルダって本当に便利なんだね!!

他にも、リクエストから送られてくる:idの値をコントローラのアクションで直接使えるんだ。これがアクションで特定の社員の情報を取得するのにとても役立つんだよ。

ぴかわかさん

:idパラメータのリクエスト処理

リクエストから送信された:idの値は、showアクション内で利用することができます。特定の社員情報をデータベースから取得するのに役立ちます。

例えば、リクエストがGET /employees/3の場合、:id3に置き換わり、この値がshowアクションに渡されます。showアクションでは、この3を使って、employeesテーブルからidが3の社員の情報を取得することができます。

現在、showアクションはまだ実装されていませんが、将来的にはリクエストから送られてくる値を使用して、データベースから特定の社員の詳細情報を取得する処理を行う予定です。そのため、リクエストで/employees/に続く値は、データベースに保存されている社員を一意に識別するユニークな数字(通常は主キー)である必要があります。

例えば、employeesテーブルのid1であるレコードが田中さんの情報である場合、その詳細情報を取得するにはGET /employees/1というリクエストを送信します。

これにより、showアクション内でこの1を利用してデータベースから田中さんの詳細情報を取得する処理を行うことができるようになります。

このように、社員の詳細情報を表示するためには、Webブラウザから送信されるリクエストURLの末尾に特定の社員の主キーを含めることがポイントです。

それでは、ルーティングが正しく設定されているかを確認しましょう。

ルーティングが適切に設定されているかを確認しましょう

config/routes.rbファイルに社員の詳細を表示するためのルートが以下のように適切に設定されているか確認してください。

この設定により、employeesコントローラのshowアクションに対応付けられます。

showアクションの実装

employeesコントローラのshowアクションでは、リクエストから送られてくる:idの値を使って、データベースから特定の社員の詳細情報を取得する処理を実装します。

以前学習した通り、データベースのテーブルから特定のレコードを取得する際には、ActiveRecordのfindメソッドを利用する方法があります。

主キー値に対応するレコードを取得する
1
モデルのクラス名.find(主キー値)

たとえば、Employee.find(1)とすることで、employeesテーブルのid1のレコードを取得できます。この場合、田中さんの情報が取得されます。

例 | 主キー値が1のレコードを取得する
1
Employee.find(1)

showアクションでは、このfindメソッドを使用して取得したデータをビューに渡すため、結果をインスタンス変数@employeeに代入します。indexアクションで複数の社員情報を取得した場合と異なり、showアクションでは、一人の社員情報のみを扱うので、インスタンス変数の名前は単数形@employeeとします。

例 | employeesコントローラ内
1
2
3
4
5
6
7
def index
  @employees = Employee.all #複数の社員情報を取得
end

def show
@employee = Employee.find(1) #1人の社員情報を取得
end

ただし、Employee.find(1)を直接コードに記述すると、常にid1の社員情報のみを取得することになり、他の社員の詳細情報を表示することはできません。

実際には、リクエストから送信される:idの値を動的に取得して、要求される社員情報を取得する必要があります。以前ルーティングで学んだ通り、リクエストの/employees/に続く任意の値が:idに置き換わり、showアクション内で利用することができます。

この:idの値は、パラメータとして扱われます。パラメータとは、リクエストと共に送られる追加情報のことで、この場合は:idがその一つです。

パラメータへのアクセス方法

コントローラのアクション内では、paramsというハッシュのようなオブジェクトを使ってパラメータにアクセスします。params[:id]と書くことで、リクエストURLの:id部分に対応する値を取得できます。

findメソッドにparams[:id]を引数として使用することで、指定されたidを持つ社員の情報をデータベースから取得できます。この方法は、さまざまなidに対応する社員情報を動的に取得するのに役立ちます。

この方法により、動的に異なる社員の情報を取得することが可能です。

例 | employeesコントローラ内
1
2
3
def show
  @employee = Employee.find(params[:id])
end

例えば、リクエストがGET /employees/3の場合、:idのパラメータは3となります。その結果、params[:id]3を取得し、Employee.find(params[:id])は実質的にEmployee.find(3)として機能します。

例 | リクエストがGET /employees/3の場合のshowアクション
1
2
3
4
5
def show
  # params[:id]が3を取得するため、
  # 以下のコードはEmployee.find(3)と同じ結果を返します
  @employee = Employee.find(params[:id])
end
showアクションを実装しましょう

リクエストに含まれるパラメータを利用してデータベースから特定の社員の詳細情報を取得するため、employeesコントローラのshowアクションを実装しましょう。

showアクション内に、以下のハイライトされた行を追加してください。

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
class EmployeesController < ApplicationController
  def index
    # 社員の一覧を取得する処理
    @employees = Employee.all
  end

  def show
    # 特定の社員の詳細情報を取得する処理
@employee = Employee.find(params[:id])
end # ... [後略] ... end
ぴっかちゃん

なるほど、params[:id]を使ってリクエストから送られた値を取得しているんだね。でも、その仕組みがまだピンとこないな…。

その動きを実際に見て理解を深めよう。次は、Pry-Railsを使って、paramsの中身を直接確認してみよう!<

ぴかわかさん
ポイント
  1. リクエストに含まれる追加情報は「パラメータ」と呼ばれ、URLやフォームデータなどに含まれる。
  2. パラメータは、paramsというハッシュのようなオブジェクトを通じて、コントローラのアクション内でアクセスできる。
  3. 特定のパラメータにアクセスするには、paramsオブジェクトの後に括弧とシンボルを使用し、例えばルーティングで定義された:idのプレースホルダに対応する値にはparams[:id]としてアクセスできる。

Pry-Railsでparamsの詳細確認

Pry-Railsを使って、paramsの中身を確認し、リクエストから送信された情報がどのように処理されているのかを理解しましょう。これにより、paramsオブジェクトがどのようにアクション内で使用されているかを具体的に確認できます。

コードにブレークポイントbinding.pryを挿入しましょう

まず、showアクション内にbinding.pryを挿入します。これにより、プログラムの実行がこの行で一時停止し、コードの状態を確認できるようになります。

app/controllers/employees_controller.rb | binding.pryを追加する
1
2
3
4
5
6
7
class EmployeesController < ApplicationController
  def show
    # 特定の社員の詳細情報を取得する処理
binding.pry # この行で一時停止して、パラメータを確認する
@employee = Employee.find(params[:id]) end end
プログラムを通常どおりに実行しましょう

コードにbinding.pryを挿入した後、プログラムを通常通りに実行します。rails sでサーバーを起動し、WebブラウザのURLの末尾に/employees/3を追加してアクセスしてみましょう。

プログラムはbinding.pryで一時停止し、ブラウザは読み込み中の状態になります。この状態は、サーバー側の処理がbinding.pryに到達してコード内で実行された結果、プログラムがその地点で一時的に実行を停止しているため発生すると以前学びましたね。

このとき、rails sで起動したサーバーのコンソールを確認すると、以下のようにPryプロンプトが表示されていることがわかります。ここでparamsの中身を確認できます。

Pryコンソールでparamsの中身を確認しましょう。

Pryコンソールで以下のコマンドを実行し、paramsの中身と、特にparams[:id]の値を確認します。/employees/3にアクセスした場合、params[:id]の値は3になるはずです。

  • paramsを入力し、全てのパラメータを確認する。
  • params[:id]を入力し、:idの値を確認する。

まずは、paramsを入力すると、リクエストに含まれるパラメータの一覧が表示されます。表示された{}の中の情報から、このリクエストがEmployeesControllershowアクションに関連しており、:idパラメータが3であることが分かります。

次に、params[:id]を入力すると、リクエストURLの:id部分に対応する値を取得することができます。/employees/3へのリクエストの場合、以下のようにparams[:id]3となります。

さらに、Employee.find(params[:id])を実行してみましょう。以下のようにid3の社員情報が取得できていることが確認できます。

このように、params[:id]findメソッドの引数として使うことで、リクエストの要求されるidの社員情報をデータベースから取得することができます。この場合、高橋さんの情報を取得します。

binding.pryを削除しておきましょう。

最後に、binding.pryを必ず削除しておきましょう。

app/controllers/employees_controller.rb | binding.pryを削除する
1
2
3
4
5
6
class EmployeesController < ApplicationController
  def show
    # 特定の社員の詳細情報を取得する処理
    @employee = Employee.find(params[:id])
  end
end

binding.pryを削除した後は、Pryコンソールでexitを実行し、コンソールを終了しましょう。これで、Pry-Railsを使ってparamsの中身を確認し、動的なリクエストの処理を理解することができました。

詳細ビューの作成

社員の詳細情報を表示するためのビューを作成しましょう。以下は、完成した社員の詳細画面の例です。

showアクションでは、リクエストされたURLからidの値を取得してデータベースから該当する社員情報を取得し、@employeeというインスタンス変数に代入しています。

employeesコントローラ内
1
2
3
4
def show
  # params[:id]からidの値を取得し、該当する社員情報を取得
  @employee = Employee.find(params[:id])
end

この@employeeは、showアクションに対応するビューファイルで使用できます。しかし、showアクションに対応するビューファイルはまだ存在しないので、作成しましょう。このビューでは、リクエストから要求される社員の詳細情報をユーザーに表示します。

show.html.erbファイルを作成しましょう。

app/views/employeesディレクトリにshow.html.erbというファイルを作成しましょう。このファイルには、次のようなコードを記述します。

app/views/employees/show.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<h2>社員詳細情報</h2>

<table>
  <tbody>
    <tr>
      <th>名前</th>
      <td><%= @employee.name %></td>
    </tr>
    <tr>
      <th>生年月日</th>
      <td><%= @employee.birthday %></td>
    </tr>
  </tbody>
</table>

<a href="/employees">社員情報一覧に戻る</a>

このビューでは、@employeeのインスタンス変数から社員の名前や生年月日などの詳細情報を取り出し、テーブル形式で表示しています。

Webブラウザでアクセスしてみましょう。

次に、サーバーを起動して、WebブラウザのURLの末尾に/employees/1を追加してアクセスしてみましょう。すると、以下の画像のように田中さんの情報が表示されるはずです。

このようにして、各社員の詳細情報を表示するビューを作成し、動的なWebアプリケーションを作成する基本的な流れを学びました。次に、この情報をさらに深く理解するために、Pry-Railsを使用して内部の動作を確認しましょう。

ぴっかちゃん

一覧表示ではeachメソッドを使って複数の社員情報をビューに表示したね。でも、詳細表示ではその必要がないんだね。

そうなんだ。詳細表示ではshowアクションで1人分の社員情報だけを取得するから、@employee.nameで直接名前を取得できるんだ。Pry-Railsで実際に中身を見てみようか。

ぴかわかさん
詳細のビューファイルにbinding.pryを挿入しましょう

まずは、show.html.erbファイルにbinding.pryを挿入し、コントローラーからビューに渡されるインスタンス変数の@employeeの内容を確認しましょう。binding.pryは以下のように挿入します。

app/views/employees/show.html.erb | binding.pryを挿入する
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<h2>社員詳細情報</h2>
<% binding.pry %>
<table> <tbody> <tr> <th>名前</th> <td><%= @employee.name %></td> </tr> <tr> <th>生年月日</th> <td><%= @employee.birthday %></td> </tr> </tbody> </table> <a href="/employees">社員情報一覧に戻る</a>

rails sでサーバーを起動し、WebブラウザのURLの末尾に/employees/1を追加してアクセスしてみましょう。この時、rails sで起動したサーバーのコンソールでPryプロンプトが表示されていることを確認します。

Pryコンソールで@employeeを確認してみましょう。

Pryコンソールに@employeeと入力して実行しましょう。すると、以下のようにid1の社員情報を含むEmployeeクラスのインスタンスが表示されます。この場合、田中さんの情報が表示されるはずです。

@employeeは、indexアクションで取得した@employeesのように複数のEmployeeクラスのインスタンスを含んでいません。したがって、eachメソッドを使用する必要がなく、@employee.nameと記述することで直接名前にアクセスできます。

@employee.nameや@employee.birthdayを確認してみましょう。

Pryコンソールで@employee.name@employee.birthdayをそれぞれ実行しましょう。

これにより、田中さんの名前や生年月日に正しくアクセスできていることを確認できます。ビュー内での<%= @employee.name %><%= @employee.birthday %>は、それぞれ適切な値を生成していることになります。

binding.pryを削除しましょう

ビューファイルからbinding.pryを削除しましょう。

app/views/employees/show.html.erb | binding.pryを削除する
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<h2>社員詳細情報</h2>

<table>
  <tbody>
    <tr>
      <th>名前</th>
      <td><%= @employee.name %></td>
    </tr>
    <tr>
      <th>生年月日</th>
      <td><%= @employee.birthday %></td>
    </tr>
  </tbody>
</table>

<a href="/employees">社員情報一覧に戻る</a>

最後に、Pryコンソールで「exit」を実行しましょう。これでPry-Railsで@employeeの内容を確認する作業は完了です。

他の社員の詳細画面にも移動してみましょう

これまでに学んだことを活かして、田中さん以外の社員の詳細情報にもアクセスしてみましょう。WebブラウザのURLの末尾を/employees/2/employees/3など、2から6までの数字に変更してアクセスしてみてください。

Webブラウザで異なるURLにアクセスすることで、それぞれの社員IDに対応した詳細画面が表示されることを確認しましょう。

ぴっかちゃん

詳細画面が社員ごとに変わるのを見ると、params[:id]がどれだけ重要かがわかるね!動的に情報を取得して表示するってすごい!

その通りだよ、ぴっかちゃん。この仕組みによって、アプリケーションはユーザーの要求に応じて内容を変更できるんだ。

ぴかわかさん

一覧画面に詳細画面へのリンク追加

社員一覧画面から各社員の詳細情報に直接アクセスできるようにするため、詳細情報へのリンクを追加しましょう。このリンクによって、一覧画面から直接、各社員の詳細情報を表示する画面に移動できるようになります。

これまで学んだ内容から、リクエストURLの末尾に特定の社員のidを指定することで、その社員の詳細情報にアクセスできることがわかりました。詳細情報リンクをクリックする際は、リクエストにその社員を一意に識別するidを含める必要があります。通常、この識別情報は、データベースに格納されている社員の一意なid(主キー)です。

たとえば、idが1の田中さんの詳細ページへのリンクは、/employees/に続けて1を追加することで作成できます。このリンクをクリックすると、指定されたURLに対してGETリクエストが送信され、showアクションで指定された社員の詳細情報を取得することができます。

例 | IDが1の田中さんの詳細画面へのリンク
1
<a href="/employees/1">社員の詳細情報を見る</a>

以下の画像のようにリンクをクリックすると、Webブラウザは該当する社員の詳細情報画面を表示します。アドレスバーのURLも/employees/から/employees/1に変わることが確認できます

それでは、各社員の詳細ページへのリンクを作成していきましょう。

新しいヘッダー列と詳細ページへのリンクを追加しましょう

社員一覧画面に各社員の詳細ページへのリンクを追加することで、一覧から直接個々の社員情報にアクセスできるようになります。以下のコードをindex.html.erbに追記してください。

app/views/employees/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<h2>社員情報一覧</h2>

<table>
  <!-- テーブルのヘッダー -->
  <thead>
    <tr>
      <th>名前</th>
      <th>生年月日</th>
<th>詳細</th>
</tr> </thead> <!-- テーブルのボディ --> <tbody> <% @employees.each do |employee| %> <tr> <td><%= employee.name %></td> <td><%= employee.birthday %></td>
<td><a href="/employees/<%= employee.id %>">詳細情報</a></td>
</tr> <% end %> </tbody> </table>

この<a href="/employees/<%= employee.id %>">詳細情報</a>の部分では、各社員インスタンスのid属性を取得し、URLの一部として動的に挿入しています。この方法により、それぞれの社員に対応するユニークなリンクを生成します。

@employeesには、indexアクションで取得した複数の社員情報が含まれています。

eachメソッドを使用することで、このコレクション内の各社員に対して繰り返し処理を行い、<%= employee.id %>を用いてその社員の詳細ページへのリンクを動的に生成しています。

例えば、社員のIDが1の場合は/employees/1、IDが2の場合は/employees/2というように、各社員の詳細ページへの正確なパスがリンクとして設定されます。

Webブラウザで動作を確認しましょう

新しいヘッダー列と詳細ページへのリンクを追加したら、Railsサーバーを起動し、Webブラウザで/employeesにアクセスし、変更が正しく反映されているか確認してください。

また、「詳細情報」のリンクをクリックして、その社員の詳細情報が表示される詳細画面に正しく移動することを確認してください。

この実装を通じて、ユーザーは一覧画面から直接任意の社員の詳細情報にアクセスできるようになりました。このアクセスの簡易化により、情報を迅速に見つけることが可能になり、アプリケーションの使い勝手が向上します。

ぴっかちゃん

社員情報の一覧表示と特定の社員の詳細情報を表示できるようになったよ!これって、データを読み取るアプリケーションの基本だよね。

その通り、!これらのスキルはアプリケーション開発の土台だから、今後も色々な場面で役に立つよ!

ぴかわかさん

さいごに

今回は、社員一覧と社員詳細という2つの画面を作ることで、Webアプリケーションでのデータの表示方法について基本を学びました。これらの基本を押さえることで、ユーザーにとってわかりやすい情報の見せ方ができるようになります。

この記事のまとめ

  • Pry-Railsを利用する際には、デバッグやコードの挙動を理解したい箇所にbinding.pryというブレークポイントを挿入する
  • indexアクションでは、複数の社員情報を扱うので、インスタンス変数は複数形の@employeesを使用する
  • showアクションでは、一人の社員情報のみを扱うので、インスタンス変数の名前は単数形の@employeeを使用する