すでにメンバーの場合は

無料会員登録

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

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

Pikawakaにログイン

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

データ作成画面の作成(Create)

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

はじめに

概要

この記事では、Ruby on Railsフレームワークを使用して、データベースに新しいデータを作成する方法を学びます。具体的には、新規登録画面の作成からデータの送信、データ保存までの一連の流れに焦点を当てます。特にform_withを使って、効率的かつ直感的にフォームを作成し、送信されたデータをデータベースに保存する方法を詳しく解説します。

目標

この章の目標
  • 新規登録画面の作成とルート設定の方法を理解し、実践する。
  • ユーザーからの入力を受け取るフォームの作成方法と、form_withを使ったデータの送信方法を学ぶ。
  • 送信されたデータをデータベースに安全に保存するプロセスを理解し、Railsアプリケーションでのデータ管理の基本を習得する。
この章で完成するもの

この章では、新しい社員の情報をデータベースに登録するための「データ作成画面」を実装します。この画面の主な目的は、一覧画面に追加される「新規作成」リンクをクリックした際に、ユーザーが新しい社員の情報を入力して登録することです。

データ作成画面では、部署情報も取り扱います。最終的には、以下の画面の例のように、部署を選択できる機能を実装します。

この画面の中心は、新しい社員の情報を入力するフォームです。フォームの下には「登録する」というボタンがあり、このボタンをクリックすると、入力したデータがデータベースに保存されます。

学習を段階的に進めるために、最初は部署選択機能を含まずに画面の作成を始めます。

登録完了後は、以下のように登録した社員(この場合は、西本知子さん)の名前が登録完了ページに表示されるようにします。

それでは、新規社員登録機能の実装に取り組みましょう!

ぴかわかさん

1. 新規登録のためのルート確認

新しい社員を登録するためには、2つの重要なルートが必要です。

新規登録画面へのアクセス

社員の新規登録を行うには、最初に登録フォームの画面を表示する必要があります。新規登録フォームの表示は、WebブラウザからGET /employees/newのリクエストを送信します。画面の表示をリクエストするため、HTTPメソッドはGETになります。

このリクエストはemployeesコントローラのnewアクションで処理されます。

まだ未実装ですが、GET /employees/newのリクエストを送信すると、将来的には以下のような新規登録画面が表示される予定です。ここで重要なのは、このリクエストがデータの登録処理を行うのではなく、社員の情報を入力するためのフォームを表示することです。

ぴっかちゃん

なるほど、新規登録はフォームの表示から始まるんだね。

最初にGET /employees/newでフォームを表示し、そこから新しい社員の情報を入力していくんだ。

ぴかわかさん

新規登録データの送信

新規登録フォームに社員の情報を入力した後、次のステップは、入力されたデータをRailsアプリケーションに送信し、新規社員としてデータベースに登録することです。この操作は、POST /employeesという形式のリクエストをWebブラウザから送信します。データをサーバーに送信するため、HTTPメソッドはPOSTになります。

このリクエストはemployeesコントローラのcreateアクションで処理されます。

新規登録に関するルートを整理してみましょう。

最初に、GET /employees/newというリクエストを送信してnewアクションで新規登録フォームを表示させます。

次に、社員の情報をフォームに入力し、完了したら「登録する」というボタンをクリックします。この操作により、入力したデータを含むPOST /employeesのリクエストが送信されます。createアクションは、この送信されたデータを受け取り、新規社員としてデータベースに登録する処理を行います。

ぴっかちゃん

なるほど!新しい社員を登録する過程って、2つのステップから成り立っているんだね。

その通りだよ。最初にnewアクションを使って入力フォームを表示し、次にcreateアクションでその入力データを受け取り、データベースに保存するんだ。この流れをしっかり把握しておくといいよ。

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

config/routes.rbファイルを開いて、新規登録画面を表示するためのnewアクションへのルートと、データを新規登録するためのcreateアクションへのルートが正しく設定されていることを確認してください。

この設定により、新規登録画面を表示するリクエストはemployeesコントローラのnewアクションに、データを新規登録するリクエストは、createアクションに対応付けられます。

2. 新規登録ビューとリンクの作成

新規登録画面のビューを作成し、一覧画面からこのビューに簡単にアクセスできるリンクを追加します。フォームの実装に関しては、あとで行います。この段階では、リクエストの流れとビューの表示方法について理解を深めます。

一覧画面にある「新規作成」リンクからGET /employees/newのリクエストを送信すると、以下の画像のようなシンプルなビューが表示されることを目指します。

新規登録ビューの作成

新規登録画面を表示するためのビューを作成することから始めましょう。ここでは、newアクションに対応するシンプルなビューをnew.html.erbに設定します。

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

app/views/employeesディレクトリにnew.html.erbファイルを作成し、以下のコードを記述してください。

app/views/employees/new.html.erb
1
2
3
<h2>新規社員登録</h2>

<a href="/employees">社員情報一覧に戻る</a>
Webブラウザで新規登録画面にアクセスしてみましょう。

サーバーを起動し、Webブラウザで/employees/newにアクセスして、以下のように新規登録画面が表示されることを確認しましょう。

一覧画面へのリンク追加

次に、一覧画面に新規登録画面へ簡単にアクセスできる「新規作成」リンクを追加します。これにより、ユーザーは一覧画面から直接新規登録画面に移動できるようになります。

新規登録画面にアクセスするためには、GET /employees/newというリクエストを送信する必要があります。

このリクエストは、aタグにhref="/employees/new"を指定することで、GETメソッドによるリクエストとして簡単に送信できます。

新規登録画面へのリンク
1
<a href="/employees/new">新規作成</a>
一覧画面に「新規作成」のリンクを追加しましょう

index.html.erbファイルの以下のハイライトされる部分を変更して、「新規作成」リンクを設置しましょう。

app/views/employees/index.html.erb | 変更箇所
1
2
3
4
5
6
7
8
9
10
11
<div class="employee-navigation">
<h2>社員情報一覧</h2>
<a href="/employees/new">新規作成</a>
</div>
<table> <!-- テーブルのヘッダー --> <thead> <tr> <th>名前</th> <!-- 中略ー -->
リンクのスタイルを適用しましょう

見た目を整えるために、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
body {
  display: flex;
  flex-direction: column;
}

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

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

.employee-navigation {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
table td { background-color: #fff2e2; padding: 10px 20px; } // ... [後略] ...
Webブラウザでリンクの動作を確認しましょう

サーバーが起動されていることを確認して、Webブラウザで/employeesにアクセスしてみましょう。一覧画面に「新規作成」リンクが表示されていることを確認します。

リンクをクリックして、新規登録画面に遷移するかも確認しましょう。

これで、新規登録ビューの作成と一覧画面からのリンク追加が完了しました。次のセクションでは、フォームの実装とデータの送信について学んでいきます。

3. データ入力フォームの基本と送信

新規社員の登録に必要なフォームを段階的に作成し、データの送信方法を学びます。まずは、HTMLでのフォームの基本的な作り方から始めます。その後、Railsのform_withヘルパーを利用して、より高度なフォームを実装する方法について学びます。

以下の画像のように、新規登録フォームが表示されることを目指します。

HTTPメソッドの復習

HTMLフォームの基礎に入る前にGETPOSTのHTTPメソッドを振り返ります。

新規社員の情報をデータベースに登録するには、WebブラウザからPOST /employeesへのリクエスト送信が必要でしたね。

これまでに学んだように、GETメソッドは、主にサーバーから情報を取得するためのリクエストを行う(Webページの閲覧など)際に使用します。Webページ上のリンク(<a>タグ)をクリックすると、自動的にGETリクエストがサーバーに送信されます。

例:GETリクエストによるページアクセス
1
<a href="https://example.com/page.html">プログラミングについて徹底解説!</a>

一方で、POSTメソッドはサーバーに情報を送信する際に使用します。新規登録やログインなど、機密性の高い情報を扱う場合に適しています。POSTリクエストを送信する方法はいくつかありますが、その中でも最も一般的なのはHTMLフォームを使用したものです。

HTMLフォームは、以下のように<form>タグを使って定義されます。このタグ内でmethod属性を使用して、HTTPメソッドを指定します。

例 | HTMLフォーム
1
2
3
4
5
6
7
8
9
<!-- GETメソッドでフォームを送信する例 -->
<form action="/search" method="get">
  <!-- フォーム要素 -->
</form>

<!-- POSTメソッドでフォームを送信する例 -->
<form action="/submit" method="post">
  <!-- フォーム要素 -->
</form>

HTMLフォームはGETPOSTのどちらのメソッドでも利用できますが、新規登録やログインなど機密性の高い情報を扱う際はPOSTメソッドが適しています。例えば、お問い合わせフォームに入力されたメールアドレスは、外部に公開されたくない重要な情報です。

GETメソッドを使用すると、以下のようにURLに情報が表示されてしまうため、機密情報を扱う場合にはセキュリティ上のリスクがあります。

一方、POSTメソッドを使用すると、入力された情報はリクエストボディに格納され、URLからは見られません。これにより、機密性の高い情報を安全にサーバーに送信することができます。

このため、POSTメソッドは新規登録フォームやログインフォームなど機密性の高い情報を扱う場合に適しています。

HTMLフォームの基本と実践

HTMLフォームを通じてデータを送信する方法について学びます。

新規社員を登録する際には、POST /employeesへデータを送信するためのフォームが必要です。<form>タグのaction属性でデータ送信先のURLを指定し、method属性でHTTPメソッドをpostに設定することで、フォームデータがサーバーに安全に送信されます。

以下は、新規社員登録用のフォームを作成するためのHTMLコードの例です。

例 | 新規社員登録用フォーム
1
2
3
<form action="/employees" method="post">
  <!-- フォーム要素 -->
</form>

フォーム内には、ユーザーが情報を入力するための様々な要素(フォーム要素)を配置します。これには、テキスト入力欄や送信ボタンなどが含まれます。

フォーム要素は、主に<input>タグを使用して作成できます。type属性を指定することで、入力欄の種類を定義します。例えば、<input type="text">は一般的なテキスト入力欄を、<input type="date">は日付を選択するための入力欄を作成します。

※ name属性については、このあと学習します。

例 | フォーム要素の入力欄の基本的な作り方
1
2
3
4
<!-- テキスト入力欄 -->
<input type="text" name="name">
<!-- 日付入力欄 -->
<input type="date" name="birthday">

また、フォームのデータを送信するには送信ボタンが必要です。<input>タグにtype="submit"を指定することで、フォームを送信するボタンを作成します。さらに、value属性を使用して、ボタン上に表示されるテキストを指定できます。

以下の例では、ボタンに「登録する」と表示されます。

例: 送信ボタンの作り方
1
2
<!-- 送信ボタン -->
<input type="submit" value="登録する">

このように、<input>タグとtype属性を活用することで、フォームに必要な入力欄を柔軟に設定することができます。

name属性の機能と重要性

ユーザーがフォームに情報を入力し、送信ボタンをクリックすると、ブラウザは<form>タグに設定されたaction属性のURLに向けて、method属性で指定されたHTTPメソッドを使用してリクエストを送信します。このリクエストには、フォームに入力されたデータが含まれ、サーバー側でこれらのデータを受け取って処理します。

フォームに入力されたデータは、サーバーに送信される際、name属性に紐づいて送信されます。この属性は、フォーム内の各入力欄を一意に識別するために使用されます。

例えば、生年月日を入力する欄があるとします。この入力欄のname属性をbirthdayと設定しておくと、ユーザーが入力した日付はbirthdayという名前でサーバーに送信されます。

例 | 生年月日を入力する欄
1
<input type="date" name="birthday">

サーバーに送信されたデータは「パラメータ」として扱われ、Railsではparamsというハッシュ構造のオブジェクトに格納されます。上記の例だと、birthdayというキーの値として、params内に格納されます。そのため、ユーザーが入力した日付は、対応するコントローラのアクションでparams[:birthday]としてアクセスできます。

例 | データ取得方法
1
2
3
4
5
6
params = {
  "birthday" => "選択された日付"
  # 他のフォーム要素のデータ...
}

params[:birthday] #=> "選択された日付"

また、name属性をemployee[birthday]のようにネストされた形式で使用することで、サーバー側でデータを受け取る際に、データがネストされたハッシュの形で整理されます。これにより、複雑なデータ構造を扱う場合に、データを整理しやすくなります。

例 | name属性をネストされた形式で使用する場合
1
2
<input type="text" name="employee[name]">
<input type="date" name="employee[birthday]">

上記のようにname属性をネストされた形式で使用すると、関連するすべてのデータがparamsオブジェクト内のemployeeキー下に格納されます。

このようにname属性をネストされた形式で使用すると、params内で情報が整理されます。この方法は、フォームから送信されたデータの構造を整理しやすくし、関連するデータを一括で扱いやすくするために役立ちます。

たとえば、Railsのコントローラのアクションでは、params[:employee]を使用して、employeeキーの下にネストされたデータに一括でアクセスできます。

例 | paramsでのデータの取得方法
1
params[:employee] #=> { "name" => "入力された名前", "birthday" => "選択された日付" }

このように、ネストされたname属性を使用することで、複数の関連するデータを扱う際の複雑さを軽減できます。

Railsでは、モデルと関連するフォームでは、ネストされたname属性の使用が一般的です。このネストされた形式を覚えておくと、Railsでのフォーム処理がよりスムーズになります!

ぴかわかさん

フォームにラベル(説明文)を追加する方法

テキスト入力欄やその他のフォーム要素には、ユーザーがそれぞれのフィールドの目的を理解しやすくするために、ラベル(説明文)を付けることが一般的です。

例えば、以下の画像のようにテキスト入力欄に「名前」と「生年月日」というラベルをつけることで、ユーザーが何を入力すべきかを明確に伝えることができます。

ラベル(説明文)を付けるには、<label>タグを使用します。

以下のように、<label>タグのfor属性は、対応する<input>タグのid属性と同じ値を持たせる必要があります。

例 | ラベルの付け方
1
2
3
4
5
6
7
<!-- 名前入力欄 -->
<label for="employee_name">名前:</label>
<input type="text" id="employee_name" name="employee[name]">

<!-- 生年月日入力欄 -->
<label for="employee_birthday">生年月日:</label>
<input type="date" id="employee_birthday" name="employee[birthday]">

上記によって、名前と生年月日の入力欄にそれぞれ「名前」と「生年月日」というラベルを付けることができます。これにより、ユーザーはどの情報をどの入力欄に記入すべきかを容易に理解できます。

HTMLフォームを追加する

新規登録画面にフォームを追加しましょう

名前と生年月日を入力して新規社員を登録するフォームを作成します。new.html.erbファイルの以下のハイライトされる部分を追加してください。

app/views/employees/new.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>

<form action="/employees" method="post" class="employee-form">
<!-- 認証トークン(authenticity token)を追加する -->
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<div class="form-group">
<label for="employee_name">名前:</label>
<input type="text" id="employee_name" name="employee[name]">
</div>
<div class="form-group">
<label for="employee_birthday">生年月日:</label>
<input type="date" id="employee_birthday" name="employee[birthday]">
</div>
<div class="form-submit">
<input type="submit" value="登録する">
</div>
</form>
<a href="/employees">社員情報一覧に戻る</a>
フォームのスタイルを適用しましょう

見た目を整えるために、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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
body {
  display: flex;
  flex-direction: column;
}

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

table td {
  background-color: #fff2e2;
  padding: 10px 20px;
}

form {
margin: 25px 0;
}
.form-group {
margin-bottom: 30px;
}
input[type="text"],
input[type="date"] {
width: 100%;
height: 42px;
border: 1px solid #c0c6d6;
border-radius: 2px;
padding: 10px 16px;
margin: 8px 0;
}
.form-submit {
text-align: center;
padding-top: 20px;
font-weight: 700;
margin-bottom: 60px;
}
input[type="submit"] {
border-radius: 4px;
padding: 10px 30px;
text-align: center;
}
.footer { margin-top: 70px; padding: 6px; background: #525fe1; } // ... [後略] ...
Webブラウザで新規登録画面を確認しましょう

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

アクセスすると、以下の画像のように社員を登録するためのフォームと先ほど追加したスタイルの適用が確認できます。

データ送信の基本の理解

前のセクションで学んだ「name属性の機能と重要性」を通じて、フォームに入力されたデータがサーバーに送信される際にname属性に紐づいて送信されることを学びました。

例えば、<input>タグのname属性をbirthdayと設定しておくと、ユーザーが入力した日付はbirthdayという名前でサーバーに送信されます。このデータはRailsのコントローラのアクションでparamsオブジェクトを通してアクセス可能です。

例 | 生年月日を入力する欄
1
<input type="date" name="birthday">
例 | データ取得方法
1
2
3
4
5
6
params = {
  "birthday" => "選択された日付"
  # 他のフォーム要素のデータ...
}

params[:birthday] #=> "選択された日付"

また、name属性をemployee[birthday]のようにネストされた形式で使用すると、paramsオブジェクト内でデータが整理されます。この方法を使うと、params[:employee]を通じて、employeeキーの下にネストされた関連データに一括でアクセスできることも学びましたね。

ここでは、name属性を使用したデータの識別と取得方法について学んだ内容を、Pry-Railsを用いて実際に確認します。フォームから送信されたデータがサーバーでどのように処理され、アクセスされるかを確かめることで、理論的な理解を実践的な知識に深めます。

createアクションにブレークポイントbinding.pryを挿入しましょう

新規登録画面で社員情報を入力し「登録する」ボタンをクリックすると、入力したデータを含むPOST /employeesリクエストがサーバーに送信され、employeesコントローラのcreateアクションで処理されます。

フォームから送信されたデータを確認するために、employees_controller.rbファイル内のcreateアクションにブレークポイントを設定します。このブレークポイントを設定することで、プログラムの実行を一時停止し、送信されたパラメータを確認することが可能になります。

以下のコードのように、binding.prycreateアクション内に追加してください。

app/controllers/employees_controller.rb | binding.pryを追加する
1
2
3
4
5
6
7
8
class EmployeesController < ApplicationController
  # 中略...
  def create
binding.pry # この行で一時停止して、パラメータ(フォームから送信されたデータ)を確認
# 新しい社員を登録する処理する end # 他のアクション... end
登録フォームで新規社員を登録しましょう

新規登録画面にアクセスし、名前の入力欄に「西本知子」と入力し、生年月日の入力欄で「1974/10/23」を選択してください。その後、「登録する」ボタンをクリックします。

この操作によって、入力したデータを含むPOST /employeesのリクエストがサーバーに送信されます。そして、rails sで起動したサーバーのコンソールで確認すると、Pryプロンプトが表示されていることが確認できます。

フォームから送信されたデータの詳細を確認しましょう

フォームから送信されたデータを詳しく見てみましょう。Pryコンソールを使って、フォームで送信された全てのパラメータを確認することができます。

Pryコンソールでparamsを実行しましょう。すると、リクエストに含まれるパラメータの一覧が表示されます。表示される{}内には、employeeキーの下にフォームから送信されたデータがまとめられています。この情報を確認することで、フォームからどのようなデータが送信されたかを理解できます。

他にも、authenticity_tokenの値がありますが、これはnew.html.erbで手動で追加した認証トークンです。この認証トークンは、フォームが実際にあなたのWebアプリケーションから送信されたものであることを確認するために用いられます。

authenticity_tokenの値は、以下の画像と一致している必要はありません。

認証トークンは、new.html.erbファイル内の<%= form_authenticity_token %>というコードによって自動的に生成され、inputタグのvalue属性に設定されます。この値は、リクエスト送信時に他のフォームデータと共にサーバーに送信されます。

app/views/employees/new.html.erb | 認証トークンの追加部分
1
2
3
4
5
6
7
8
<h2>新規社員登録</h2>

<form action="/employees" method="post" class="employee-form">
  <!-- 認証トークン(authenticity token)を追加する -->
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<div class="form-group"> <!-- 後略-->

Railsでは、フォームデータを送信する際、認証トークン(authenticity token)が必要です。この認証トークンがフォームに含まれていない場合、Railsはエラーを発生させます。これは、フォームが正規のWebアプリケーションから送信されたものであることを保証するためのセキュリティ対策です。

employeeキーの値を確認しましょう

Pryコンソールで、params[:employee]を入力し、employeeキーの値を確認してください。この操作により、employeeキーに関連するデータが表示されます。

次に、employeeキーにネストされたフォームデータの値にアクセスします。

name属性をemployee[name]のようにネストされた形式で使用したフォームからデータを送信した場合、paramsではデータがネストされたハッシュとして格納されます。

そのため、params[:employee][:name]params[:employee][:birthday]を実行ことで、それぞれの具体的な値にアクセスできます。

Pryコンソールでparams[:employee][:name]params[:employee][:birthday]を実行しましょう。実行すると、フォームに入力された「西本知子」と「1974-10-23」が表示されます。

この操作により、new.html.erbファイルで追加したフォームのinputタグのname属性がどのように機能しているかを理解することができましたね。

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

最後に、Pryコンソールからexitコマンドで抜け出し、binding.pryを削除しておきましょう。

app/controllers/employees_controller.rb | binding.pryを削除する
1
2
3
4
5
class EmployeesController < ApplicationController
  # ...中略
def create
# 新しい社員を登録する処理
end

これで、Pry-Railsを用いてparams内のフォームデータの内容の確認作業は完了しました。

4. form_withによるフォーム作成

Railsには、動的にHTMLフォームを作成するためのform_withという便利なヘルパーメソッドがあります。このメソッドを使用することで、HTMLフォームを手動で一から記述するよりも、コードの量を減らすことができ、フォームのセキュリティも強化されます。

さらに、form_withモデル(データを扱う部分)と連動して簡単にフォームを作れる点も魅力です。これにより、ユーザーが入力する情報を効率的に扱うことが可能です。

「form_with」の使い方を理解するためには、まずは基本を押さえることが大切です。HTMLフォームと「form_with」を使ったフォームのコードを比較しながら、その違いと特徴を順を追って説明しますね。

ぴかわかさん

フォームの基本構造の比較

HTMLフォームでは、<form>タグのaction属性でデータ送信先のURLを、method属性でHTTPメソッドを指定していました。さらに、認証トークンも手動でフォームに追加していました。

例 | HTMLフォーム
1
2
3
4
<form action="/employees" method="post">
  <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
  <!-- フォーム要素 -->
</form>

上記のHTMLフォームは、Railsのform_withヘルパーを使用すると、以下のように書き換えられます。

例 | form_withを使用したフォーム
1
2
3
<%= form_with(model: @employee, local: true) do |f| %>
  <!-- フォーム要素 -->
<% end %>

form_withメソッドの引数は、通常ハッシュ形式で指定されます。この引数に渡す様々な値を組み合わせることにより、さまざまな種類のフォームを作成することができます。

form_withメソッドでmodelという引数を使用すると、指定されたモデルオブジェクト(例えば@employee)に基づいて、送信先URLとHTTPメソッドが自動的に設定されます。さらに、セキュリティのための認証トークンも自動的にフォームに追加されます。

localではリクエストの送信方法を指定するために用いられ、local: trueを設定すると、フォームのデータは通常のHTTPリクエストとして送信されます。

引数のmodel: @employeeについてもう少し詳しくみていきます。

model:に指定された@employeeは、フォームに関連付けられるモデルのインスタンスです。Railsでは、このインスタンスの状態に基づいて、適切なアクションのURLとHTTPメソッドが自動で設定されます。

ここで言う「インスタンスの状態」とは、インスタンスが新規作成用なのか、既存のレコードの更新用なのかを指します。例えば、Employee.newEmployee新しい空のインスタンスを生成します。このインスタンスではidなどの値はnilとなります。

このように生成されたインスタンスは、まだデータベースに保存されていない新規のオブジェクトです。この新しいインスタンスが@employeeに代入されている場合、Railsはこのインスタンスを新規作成用として認識します。

例 | employeesコントローラ
1
2
3
  def new
    @employee = Employee.new # Employeeの新しい空のインスタンスを生成
  end

このため、form_withは自動的にこのオブジェクトが新規作成用であると判断し、フォームの送信先URLをcreateアクションに設定し、使用するHTTPメソッドをPOSTに設定します。

新規登録画面はnewアクションのルートによって表示されます。

そのため、Employeeの新しい空のインスタンスはnewアクション内で生成し、@employeeに代入します。これにより、新規登録フォームを表示するnew.html.erbビューに@employeeを渡し、利用することが可能になります。

おさえておきたいポイント

ここで重要なのは、インスタンスの生成を「createアクション」ではなく、「newアクション」で行うことです。この点は間違いやすいですが、newアクションでインスタンスを生成することにより、フォームに必要な初期状態を設定し、ユーザーが新規登録を行うための入力フィールドを提供できます。createアクションは、フォームの入力が完了した後のデータ処理を担うためのものであり、新規登録画面の表示自体はnewアクションの責務です。

idやクラスの付与方法

フォームのHTML要素にidやクラスを指定する場合は、form_withの引数にid: 'id名'class: 'クラス名'を追加します。ここで指定する値は文字列であることに注意しましょう。例えば、以下のように記述します。

1
2
3
<%= form_with(model: @employee, local: true, id: 'new_employee_form', class: 'employee-form') do |form| %>
  <!-- フォームの内容 -->
<% end %>

引数の括弧を省略できる

メソッドの引数がハッシュの場合、括弧を省略して以下のように記述することができます。少しわかりにくいかもしれませんが、form_withの後に続く部分からdoの直前までが引数として扱われます。

例 | form_withを使用したフォーム
1
2
3
<%= form_with model: @employee, local: true do |f| %>
  <!-- フォーム要素 -->
<% end %>
ぴっかちゃん

RailsはRubyで書かれているんだよね。Rubyって引数の省略形をよく使うんだって聞いたことがあるよ。

その通りだよ。Rubyではこのような引数の括弧を省略することが一般的だよ。説明では括弧を使ってわかりやすくするけど、実際にアプリケーションに実装する際には、省略形で記述するよ。

ぴかわかさん

学んだ内容をアプリケーションに適用する

newアクションでEmployeeモデルのインスタンスを作成しましょう

まず、newアクションでEmployeeモデルの新しい空のインスタンスを作成し、@employeeに代入します。これにより、form_withメソッドは@employeeを新規登録フォーム用のインスタンスとして認識します。

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

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

  def new
    # 新しい社員の登録フォームを表示する処理
@employee = Employee.new
end # ... [後略] ... end

このように@employeeには、Employeeの新しい空のインスタンスが代入されているため、form_withはこれを新規登録用のフォームとして扱います。

form_withを使用してみましょう

new.html.erbファイル内でのフォームをform_withを使用した形に変更します。これまでの<form>タグをform_withメソッドで置き換えます。

ここまで学習した内容だけを変更します。

app/views/employees/new.html.erb | 変更箇所の確認
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h2>新規社員登録</h2>

<form action="/employees" method="post" class="employee-form">
<!-- 認証トークン(authenticity token)を追加する -->
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<div class="form-group"> <label for="employee_name">名前:</label> <input type="text" id="employee_name" name="employee[name]"> </div> <!-- 後略 -->
</form>
<a href="/employees">社員情報一覧に戻る</a>

new.html.erbファイルを開いて、上記のハイライトされる箇所に以下の変更を行ってください。form_withを使用する場合、認証トークンは自動的に生成されるため、手動で追加する必要はありません。このため、認証トークンに関するコード行は削除しましょう。

app/views/employees/new.html.erb | 変更後
1
2
3
4
5
6
7
8
9
10
11
12
<h2>新規社員登録</h2>

<%= form_with model: @employee, local: true, class: 'employee-form' do |f| %>
<div class="form-group"> <label for="employee_name">名前:</label> <input type="text" id="employee_name" name="employee[name]"> </div> <!-- 後略 -->
<% end %>
<a href="/employees">社員情報一覧に戻る</a>

上記の変更により、form_with@employeeというモデルオブジェクトをベースに新規登録用のフォームを作成します。local: trueはフォームを通常のHTTPリクエストとして送信するように指定し、class: 'employee-form'はCSSクラスをフォームに適用します。

次はフォーム要素について確認していきましょう

ぴかわかさん

フォーム要素の作成

form_withを使用したフォーム要素の作成は、フォームのブロック内で行います。

このブロック内では、ブロック引数として渡されるフォームビルダーオブジェクト(この例ではf)を使用して、様々なフォーム要素(テキストボックス、セレクトボックス、チェックボックス、送信ボタンなど)を作成できます。

フォームビルダーオブジェクトは、フォーム内の各要素を簡単に生成し、管理するための便利な方法を提供します。

form_withを使用したフォーム要素の基本構文は、以下のようになります。

基本構文
1
2
3
4
5
<%= form_with(model: モデルオブジェクト, local: true) do |f| %>
<%= f.フィールドタイプ :属性名 %>
<%= f.label :属性名, 'ラベルテキスト' %>
<%= f.submit '送信ボタンのテキスト' %>
<% end %>

フィールドタイプの指定

まずは、f.フィールドタイプです。指定したフィールドタイプによって、テキストボックス、セレクトボックス、チェックボックスなど、ユーザーがデータを入力するための特定の領域(フォームフィールド)を作成することができます。

フィールドタイプには、主に以下の種類があります。

フィールドタイプ 説明
text_field テキスト入力欄を作成します。一般的なテキストデータの入力に使用されます。
date_field 日付入力欄を作成します。日付の入力に使用されます。
select セレクトボックス(ドロップダウンメニュー)を作成します。リストから選択する形式の入力に使用されます。
check_box チェックボックスを作成します。複数選択が可能なオプションに使用されます。
email_field Eメールアドレス入力欄を作成します。Eメール形式のテキスト入力に適しています。

これらのフィールドタイプは、form_withのブロック内で、ブロック引数(ここではf)を利用して簡単に作成できます。例えば、f.text_fieldf.date_fieldを使って、それぞれテキスト入力欄や日付入力欄を生成することが可能です。

例 | フィールドタイプの指定によるフォーム要素の作り方
1
2
3
4
<%= form_with(model: モデルオブジェクト, local: true) do |f| %>
<%= f.text_field :属性名 %><!-- 指定する属性に紐付くテキスト入力欄 -->
<%= f.date_field :属性名 %> <!-- 指定する属性に紐付く日付入力欄 -->
<% end %>

:属性名とは

次に、フィールドタイプの後に指定される:属性名を確認していきましょう。

:属性名は、フォームフィールド(例えば日付入力欄など、ユーザーがデータを入力するための特定の領域)がモデルのどの属性に対応しているかを指定します。モデルの属性は、Railsのモデルで表されるデータベーステーブルのカラムに対応しています。

たとえば、Employee.newを実行すると、idnamebirthdayなどが表示されるのは、これらがEmployeeモデルの属性だからです。

次に、@employee変数にEmployeeモデルの新しい空のインスタンスが代入されている場合を考えてみましょう。この状況でform_withを使用し、f.date_field :birthdayと記述すると、この日付入力欄はEmployeeモデルのbirthday属性と紐づけられます。

例 | form_withを使用したフォーム
1
2
3
<%= form_with model: @employee, local: true do |f| %>
  <%= f.date_field :birthday %> <!-- Employeeモデルのbirthday属性に紐付く日付入力欄 -->
<% end %>

この設定により、ユーザーがこの日付入力欄に入力したデータは、Employeeモデルのbirthday属性として扱われ、サーバーに送信されます。さらに、form_withを使用すると、name属性は自動的にネストされた形式(例:employee[birthday])で生成されます。

以下は、上記のform_withを使用したフォームをHTMLフォームに書き換えた例です。

例 | HTMLフォーム
1
2
3
4
<form action="/employees" method="post">
  <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<input type="date" name="employee[birthday]"> <!-- birthday属性に紐付く日付入力欄 -->
</form>

このように、form_withでは、自動的にモデルの属性とフォームフィールドが紐づけられ、送信されたデータはネストされたハッシュ形式でparamsオブジェクトに格納されます。

したがって、HTMLフォームの時と同様に、params[:employee][:name]params[:employee][:birthday]を実行することで、具体的な値にアクセスすることが可能です。

フォームの送信ボタン

フォームの送信ボタンは、以下のようにf.submitを利用することで簡単に作成できます。送信ボタンのラベルは引数で設定(ここでは'登録する')できます。

例 | フォームの送信ボタン
1
<%= f.submit '登録する' %>

ラベルの使用

HTMLフォームでは、ラベルは通常以下のように指定されます。ここでは< label >タグのfor属性と<input>タグのid属性を同じ値に設定しています。

例 | ラベルの付け方
1
2
<label for="employee_birthday">生年月日:</label> <!-- 生年月日入力欄のラベル -->
<input type="date" id="employee_birthday" name="employee[birthday]"><!-- 生年月日入力フィールド -->

このHTMLフォームのラベルをRailsのform_withヘルパーを使用して書き換える場合、以下のようになります。f.labelメソッドを使用することで、モデルの属性に対応するラベルを生成し、紐づけることができます。

例 | form_withを使用した場合
1
2
<%= f.label :birthday, '生年月日:' %> <!-- 生年月日入力欄のラベル -->
<%= f.date_field :birthday %> <!-- 生年月日入力フィールド -->

form_withでは、ラベルと入力フィールドの属性を同じモデルの属性にすることで、ラベルとフォームフィールドが自動的にモデルの属性と紐付けられます。

form_withでフォーム要素の実装

form_withでフォーム要素を作成してみましょう

new.html.erbファイル内でのフォーム要素をform_withを使用した形に変更します。

app/views/employees/new.html.erb | 変更箇所
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<h2>新規社員登録</h2>

<%= form_with model: @employee, local: true, class: 'employee-form'  do |f| %>

  <div class="form-group">
<label for="employee_name">名前:</label>
<input type="text" id="employee_name" name="employee[name]">
</div> <div class="form-group">
<label for="employee_birthday">生年月日:</label>
<input type="date" id="employee_birthday" name="employee[birthday]">
</div> <div class="form-submit">
<input type="submit" value="登録する">
</div> <% end %> <a href="/employees">社員情報一覧に戻る</a>

new.html.erbファイルを開いて、上記のハイライトされる箇所に以下の変更を行ってください。form_withを使用する場合、自動的に対応するlabelタグとid属性が紐づけられます。つまり、f.labelf.text_field(または他のフォームフィールドヘルパー)を使用する際に、明示的にid属性を指定する必要はありません。

app/views/employees/new.html.erb | 変更後
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<h2>新規社員登録</h2>

<%= form_with model: @employee, local: true, class: 'employee-form'  do |f| %>

  <div class="form-group">
<%= f.label :name, '名前:' %>
<%= f.text_field :name %>
</div> <div class="form-group">
<%= f.label :birthday, '生年月日:' %>
<%= f.date_field :birthday %>
</div> <div class="form-submit">
<%= f.submit '登録する' %>
</div> <% end %> <a href="/employees">社員情報一覧に戻る</a>
Webブラウザで新規登録画面を確認しましょう

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

アクセスすると、以下の画像のようにHTMLフォームで実装した時と同様の社員登録フォームが確認できます。

以上でform_withによるデータ入力フォームの実装は完了です。

5.フォームデータのデータベース保存の検証

createアクションの実装に入る前に、登録フォームからのデータでデータベースに保存ができるかをPryコンソールを使用して確かめてみましょう。

createアクションにブレークポイントbinding.pryを挿入しましょう

新規登録画面で社員情報を入力し「登録する」ボタンをクリックすると、入力したデータを含むPOST /employeesリクエストがサーバーに送信され、employeesコントローラのcreateアクションで処理されます。

フォームから送信されたデータを確認するために、employees_controller.rbファイル内のcreateアクションにブレークポイントを設定します。

以下のコードのように、binding.prycreateアクション内に追加してください。

app/controllers/employees_controller.rb | binding.pryを追加する
1
2
3
4
5
6
7
8
class EmployeesController < ApplicationController
  # 中略...
  def create
binding.pry # この行で一時停止して、パラメータ(フォームから送信されたデータ)を確認
# 新しい社員を登録する処理する end # 他のアクション... end
登録フォームで新規社員を登録しましょう

新規登録画面にアクセスし、名前の入力欄に「西本知子」と入力し、生年月日の入力欄で「1974/10/23」を選択してください。その後、「登録する」ボタンをクリックします。

この操作によって、入力したデータを含むPOST /employeesのリクエストがサーバーに送信されます。そして、rails sで起動したサーバーのコンソールで確認すると、Pryプロンプトが表示されていることが確認できます。

送信されたデータをデータベースに保存してみましょう

以前学んだ通り、フォームから送信されたデータは、params[:employee][:name]params[:employee][:birthday]を使用して取得できます。これをデータベースに保存してみます。

データベースにレコードを挿入する方法は主に2つあります。1つはcreateメソッドを使う方法、もう1つはnewメソッドとsaveメソッドの組み合わせです。ここでは後者の方法を使用します。

Pryコンソールで以下のコマンドを実行して、データをデータベースに保存してみましょう。

1
2
3
4
5
# Pryコンソールでの実行
employee = Employee.new
employee.name = params[:employee][:name]
employee.birthday = params[:employee][:birthday]
employee.save

最後のemployee.saveを実行すると、以下のようにfalseが返されます。

フォームから送信されたデータをデータベースに保存しようとする際にfalseが返されるのは、Employeeモデルに必要なデータが不足しているためです。

employeesテーブルにはdepartment_idという外部キー制約を持つカラムがあり、このカラムに適切な値が設定されていなければデータベースに保存することができません。

外部キー制約の設定

ぴっかちゃん

たしか外部キー制約を設定すると、関連するテーブル間のデータの整合性と正確性が確保されるんだったよね!これによって、テーブル同士がしっかりと連携して、データの矛盾を防げるんだ。

Pryコンソールでemployeeを実行してみましょう。すると、namebirthday以外にもidcreated_atupdated_atなどの属性がありますが、これらは保存の際に自動的に設定されるため、新しいインスタンス作成時にはnilになっています。

しかし、department_idは有効な値が設定されていないと、保存は失敗します。

解決策としては、フォームに部署の選択肢を追加し、適切なdepartment_idを含むようにする必要があります。これにより、フォームからのデータが正しくデータベースに保存されるようになります。

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

最後に、Pryコンソールからexitコマンドで抜け出し、binding.pryを削除しておきましょう。

app/controllers/employees_controller.rb | binding.pryを削除する
1
2
3
4
5
class EmployeesController < ApplicationController
  # ...中略
def create
# 新しい社員を登録する処理
end

これで、Pry-Railsを利用したデータベース保存の検証作業を完了しました。

新規社員登録フォームに部署選択を追加

社員登録フォームに部署選択の機能を追加します。これにより、社員が所属する部署もフォームから選べるようになります。

部署のデータを準備しましょう

まず、Employeeモデルと関連するDepartmentモデルのデータをフォームで使用できるようにします。employees_controller.rbに必要なコードを追加します。

以下のコードをnewアクションに追加してください。

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
8
9
class EmployeesController < ApplicationController
  # ... [中略] ...
  def new
    # 新しい社員の登録フォームを表示する処理
    @employee = Employee.new
@departments = Department.all
end # ... [後略] ... end

上記では、newアクションでDepartment.allメソッドを使い、すべての部署データを取得します。取得したデータは@departmentsに代入し、newアクションに対応するビューファイル(new.html.erb)で使用することができます。

form_withによるセレクトボックスを作成方法を学ぼう

次に、登録フォームに部署を選択できるセレクトボックスの作成方法を学習します。

form_withヘルパーでは、collection_selectを使用してセレクトボックスを作成することができます。

collection_selectの基本書式
1
2
3
<%= form_with model: @employee, local: true do |f| %>
  <%= f.collection_select :属性名, コレクション, 値の方法, テキストの方法 %>
<% end %>

今回の部署を選択できるセレクトボックスの場合は、以下のように指定します。

例 | collection_selectの使い方
1
2
3
<%= form_with model: @employee, local: true do |f| %>
  <%= f.collection_select :department_id, @departments, :id, :name %>
<% end %>

collection_selectの使用方法について、1つ1つ見ていきましょう。

まず、最初に指定するのはモデルの属性名です。ここでは:department_idが指定されています。これは、セレクトボックスから選択された値が保存される属性です。

具体的には、Employeeモデルのdepartment_id属性に、ユーザーがセレクトボックスで選択した部署のidが割り当てられ、保存されます。この方法により、Employeeモデルのインスタンスがその選択された部署のidを持つことになり、関連付けが行われます。

次に、コレクションについて見ていきましょう。

collection_selectでのコレクションとは、選択リストに表示されるオブジェクトの集合です。ここでは、すべての部署データが代入された@departmentsがコレクションとして指定されています。この@departmentsは、選択リストの中で利用される値と表示テキストの両方の情報を持っています。

コレクションの次は「値の方法」です。

ここで指定される:idは、Departmentモデルの各インスタンスのid属性の値(例えば12など)を指します。

この:idは、セレクトボックスの各選択肢に対応する値(value属性)として使われ、ユーザーがセレクトボックスから部署を選択した際に、その部署のidEmployeeモデルのdepartment_id属性に保存されます。これにより、Employeeモデルのインスタンスは選択された部署に関連付けられます。

最後は「テキストの方法」です。

ここで指定される:idは、Departmentモデルの各インスタンスのname属性の値(例えば開発営業など)を指します。

この:nameは、セレクトボックスに表示される各選択肢の表示テキストとして部署の名前が使用されます。これにより、ユーザーは部署の名前を見て選択を行うことができます。

したがって、ユーザーがセレクトボックスで部署を選択すると、その部署のiddepartment_id属性としてEmployeeモデルのインスタンスに割り当てられ、部署のnameがユーザーに表示される選択肢として機能します。

例えば、セレクトボックスで「開発」を選択した際には、department_id1が関連付けられます。

セレクトボックスを追加しましょう

app/views/employees/new.html.erbを開き、以下のコードを追加してください。

app/views/employees/new.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
<h2>新規社員登録</h2>

<%= form_with model: @employee, local: true, class: 'employee-form'  do |f| %>

  <div class="form-group">
    <%= f.label :name, '名前:' %>
    <%= f.text_field :name %>
  </div>

  <div class="form-group"> 
    <%= f.label :birthday, '生年月日:' %>
    <%= f.date_field :birthday %>
  </div>

<div class="form-group">
<%= f.label :department_id, '部署:' %>
<%= f.collection_select :department_id, @departments, :id, :name %>
</div>
<div class="form-submit"> <%= f.submit '登録する' %> </div> <% end %> <a href="/employees">社員情報一覧に戻る</a>
セレクトボックスのスタイルを整えましょう

セレクトボックスの見た目を整えるために、スタイルシートを追加しましょう。app/assets/stylesheets/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
body {
  display: flex;
  flex-direction: column;
}

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

select,
input[type="text"], input[type="date"] { width: 100%; height: 42px; border: 1px solid #c0c6d6; border-radius: 2px; padding: 10px 16px; margin: 8px 0; } // ... [後略] ...
フォームの動作を確認しましょう

Webブラウザで/employees/newにアクセスし、新しい社員登録フォームが正しく表示されるか確認してください。フォームには名前、生年月日、部署選択のセレクトボックスが含まれているはずです。

また、「右クリック > 検証」でデベロッパーツールを起動し、セレクトボックスを調べると、以下のようにf.collection_selectによってselect要素を自動的に作成し、セレクトボックスのオプションが生成されていることが確認できます。

データ送信の確認をしましょう

employees_controller.rbcreateアクションにbinding.pryを追加し、フォームから送信されたデータが正しく処理されるか確認します。

以下のコードのように、binding.prycreateアクション内に追加してください。

app/controllers/employees_controller.rb | binding.pryを追加する
1
2
3
4
5
6
7
8
class EmployeesController < ApplicationController
  # 中略...
  def create
binding.pry # この行で一時停止して、パラメータ(フォームから送信されたデータ)を確認
# 新しい社員を登録する処理する end # 他のアクション... end

次に、新規登録画面にアクセスし、名前の入力欄に「西本知子」と入力し、生年月日の入力欄で「1974/10/23」、部署を「営業」に選択してください。その後、「登録する」ボタンをクリックします。

続いて、Pryコンソールでparams[:employee]params[:employee][:department_id]を続けて実行してみましょう。

すると、登録フォームでセレクトボックスから選択した営業が表示されていますね。

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

最後に、Pryコンソールからexitコマンドで抜け出し、binding.pryを削除しておきましょう。

app/controllers/employees_controller.rb | binding.pryを削除する
1
2
3
4
5
class EmployeesController < ApplicationController
  # ...中略
def create
# 新しい社員を登録する処理
end

一覧画面と詳細画面への部署表示の追加

最後に、社員一覧画面と詳細画面にも部署情報を表示しましょう。

以前、アソシエーションEmployeeモデルとDepartmentモデルの関連付けを行いました。これにより、Employeeモデルを介してDepartmentモデルの情報を簡単に取得できるようになりました。

app/models/employee.rb
1
2
3
4
class Employee < ApplicationRecord
belongs_to :department
validates :name, presence: true, length: { maximum: 30 } end
app/models/department.rb
1
2
3
4
class Department < ApplicationRecord
has_many :employees
validates :name, presence: true, uniqueness: true, length: { maximum: 30 } end

アソシエーションを使用しない場合は、個別にデータを取得する必要があります。これにより、コードが長くなり、処理も複雑になりがちです。

例えば、特定の社員の部署名を取得するには、以下のように書くことができます。

アソシエーションを使用しない場合
1
2
3
4
5
6
7
8
9
10
11
12
13
# Employeeモデルのインスタンスを取得します。
# ここでは、idが1の社員(田中さん)を取得しています。
employee = Employee.find(1)

# 田中さんが属する部署のidを取得します。
department_id = employee.department_id

# Departmentモデルから田中さんが属する部署のデータを取得します。
# ここでは、田中さんのdepartment_idに基づいて部署を取得しています。
department = Department.find(department_id)

# 田中さんの所属する部署の名前「開発」を取得します。
department_name = department.name

アソシエーションを使用すると、以下のようにEmployeeモデルから直接関連するDepartmentモデルのデータを参照できます。これにより、社員が属する部署の情報を別途データベースから検索する必要がなくなり、コードが簡潔かつ直感的になります。

アソシエーションを使用
1
2
3
4
5
6
# Employeeモデルのインスタンスを取得します。
# ここでは、idが1の社員(田中さん)を取得しています。
employee = Employee.find(1)

# 田中さんが属する部署の名前「開発」を取得します。
department_name = employee.department.name

社員一覧や詳細画面では、Employeeモデルのインスタンスが既に取得されています。

したがって、employee.department.name(個々の社員の詳細情報を表示する場合)または@employee.department.name(インスタンス変数を使用している場合)で、部署情報を簡単に画面に追加することができます。

一覧画面に部署情報を追加しましょう

まずは、以下のように一覧画面に部署情報を追加します。

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
<div class="employee-navigation">
  <h2>社員情報一覧</h2>
  <a href="/employees/new">新規作成</a>
</div>

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

WebブラウザでURLに/employeesを追加してアクセスしてみましょう。この際、rails sコマンドでサーバーが起動していることを確認してください。

アクセスすると、社員情報の一覧画面が表示されます。この画面で、先ほど追加した部署情報が含まれていることが確認できるはずです。

詳細画面に部署情報を追加しましょう

次に、以下のように詳細画面に部署情報を追加します。

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
17
18
19
20
<h2>社員詳細情報</h2>

<table>
  <tbody>
    <tr>
      <th>名前</th>
      <td><%= @employee.name %></td>
    </tr>
    <tr>
      <th>生年月日</th>
      <td><%= @employee.birthday %></td>
    </tr>
<tr>
<th>部署</th>
<td><%= @employee.department.name %></td>
</tr>
</tbody> </table> <a href="/employees">社員情報一覧に戻る</a>

一覧画面の田中さんの「詳細情報」をクリックし、以下の画面が表示されることを確認しましょう。

これで部署情報の追加は完了です。次は、登録フォームで入力したデータをデータベースに保存できるようにcreateアクションを実装します。

6. createアクションの実装とデータ保存処理

createアクションでは、POST /employeesのリクエスト時に新規登録フォームから送信されたデータをparamsを介して受け取り、Employeeモデルを利用してデータベースに保存する処理を行います。

データが保存された後は、createアクションに対応するビューで完了画面を表示するように設定します。

それでは、createアクションを編集していきましょう

ぴかわかさん

新規登録フォームからのデータ保存方法

データベースへの保存方法を確認しましょう

データベースへの保存にActiveRecordが提供するcreateメソッドを使用します。このcreateメソッドは、モデルの新しいインスタンスを生成し、同時にデータベースに保存するクラスメソッドです。

モデルの新しいインスタンスを生成して保存
1
モデルのクラス名.create(カラム名1: 1, カラム名2: 2)

employeesテーブルにデータを保存する場合、以下のように指定します。

例:Employeeモデルインスタンスの生成と保存
1
Employee.create(name: , birthday: , department_id: )

新規登録フォームに「西本知子」と「1974/10/23」が入力され、部署が「営業」に設定されたとしましょう。

登録フォームに入力されたデータは、createアクションでparamsを介して取得できます。各入力欄の値は、params[:employee][:name]params[:employee][:birthday]params[:employee][:department_id]を使用してアクセスできます。

データベースにデータを保存する際、createメソッドを使用して以下のように記述します。

例:Employeeモデルインスタンスの生成と保存
1
2
3
4
Employee.create(
  name: params[:employee][:name],
  birthday: params[:employee][:birthday],
  department_id: params[:employee][:department_id])

この場合、以下のように「西本知子」、「1974-10-23」、「2(営業)」として保存されます。

例:Employeeモデルインスタンスの生成と保存
1
2
3
4
5
Employee.create(
  name: "西本知子",
  birthday: "1974-10-23",
  department_id: 2
)

この処理をcreateアクションに記述し、@employeeに代入して、createアクションに対応するビューで使用できるようにします。

createアクションを編集しましょう。

createアクションでは、Employeeモデルを使用してフォームのデータをデータベースに保存します。paramsを使用して各フィールドの値にアクセスし、Employee.createで新しいレコードを作成します。

app/controllers/employees_controller.rbを開いて、以下のようにcreateアクションを編集してください。

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
8
9
10
class EmployeesController < ApplicationController
  # ... [中略] ...
  def create
@employee = Employee.create(
name: params[:employee][:name],
birthday: params[:employee][:birthday],
department_id: params[:employee][:department_id]
)
end end

次に、登録が完了したことをユーザーに知らせるビューファイルを作成しましょう。

ビューファイルを作成しましょう。

app/views/employeesディレクトリにcreate.html.erbファイルを新規作成します。このファイルは、登録が完了した際に表示される画面です。

以下のようにファイルを作成しましょう。

ビューファイルを編集しましょう。

create.html.erbファイルを以下のように編集し、登録完了のメッセージと新規登録された社員の名前が登録完了ページに表示され、社員情報一覧へのリンクを追加します。

app/views/employees/create.html.erb
1
2
3
4
5
<h2>登録完了</h2>

<p><%= @employee.name %>さんの登録が完了しました。</p>

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

このようにして、新規登録のフローを完了させることができます。登録が完了したら、ユーザーは一覧画面に戻ることができ、新たに登録された社員の情報を確認することが可能になります。それでは実際に社員情報を登録してみます。

登録フォームで新規社員を登録しましょう

新規登録画面にアクセスし、名前の入力欄に「西本知子」と入力し、生年月日の入力欄で「1974/10/23」、部署を「営業」に選択してください。その後、「登録する」ボタンをクリックします。

「登録する」ボタンをクリックした後、以下のように登録完了画面が表示されます。この画面には、新規に登録された「西本知子」さんの名前が表示されるはずです。

データベースに登録した社員情報を一覧画面で確認しましょう

登録完了画面から「社員情報一覧に戻る」リンクをクリックしましょう。一覧画面では、新たに追加された「西本知子」さんの情報がリストに含まれていることを確認できます。

以上の手順を経て、新規登録フォームから送信されたデータがデータベースに保存され、一覧画面に反映されていることを確認できれば、データ保存処理の実装は成功です。

最後に、セキュリティを高めるためにストロングパラメータを活用しましょう。

ぴかわかさん

ストロングパラメータの理解

ストロングパラメータ(Strong Parameters)は、Railsのセキュリティ機能の一つで、フォームからの入力データを制限するために使用されます。これにより、意図しないデータの保存を防ぎ、アプリケーションの安全性を高めることができます。

ストロングパラメータは、requireメソッドとpermitメソッドを利用します。

ストロングパラメータの基本書式
1
params.require(:モデル名).permit(:キー名)

requireメソッドとは

params.require(:モデル名)は、リクエストされたパラメータの中で指定されたモデル名に対応するキーが必ず存在していることを要求する設定です。このキーの存在は必須であるため、もし該当するキーがパラメータに含まれていない場合、エラーが発生します。

例えば、params.require(:employee)ついて考えてみましょう。

例 | requireメソッドの引数が:employeeの場合
1
params.require(:employee)

上記の指定は、リクエストされたパラメータの中に :employee というキーが必ず存在していることを要求しています。もし :employee キーがリクエストのパラメータに存在しない場合、Railsはエラーを発生させます。

require メソッドを利用することにより、期待されるキー(例えば、特定のモデルに関連するパラメータ)がリクエストに含まれていることを保証できます。

permitメソッドとは

permit(:キー名)は、params.require(:モデル名)で指定されたモデルのパラメータの中で特定のキーを許可するための設定です。これにより、許可されたキーのデータのみがコントローラのアクションで使用できるようになります。

例えば、permit(:name, :department_id) について考えてみましょう。

例 | permitメソッドで:nameと:department_idを許可する場合
1
params.require(:employee).permit(:name, :department_id)

上記の指定は、リクエストされた :employee パラメータの中で :name:department_id というキーのデータのみが使用されることを許可しています。他のキー(例えば :birthday)に関するデータは無視されます。

例えば、新規登録フォームから送信されるパラメータ(データ)は、初めに「許可されていない(permittedではない)」ことを意味するpermitted: falseが表示されます。

しかし、params.require(:employee).permit(:name, :department_id)を適用した場合、以下のように:name:department_idだけが許可され、それらのキーに関連するパラメータがpermitted: trueとしてマークされます。

:birthdayキーはこの設定では許可されていないため、そのデータは無視されます。

もし新規登録フォームで、名前の入力欄に「西本知子」と入力し、部署を「営業(2)」として選択した場合、返り値は以下のようになります。

employees_controller.rb | ストロングパラメータの例
1
2
params.require(:employee).permit(:name, :department_id)
#=> {"name"=>"西本知子", "department_id"=>"2"}

この返り値は、create メソッドの引数に渡す形式と同じです。

モデルの新しいインスタンスを生成して保存
1
2
3
モデルのクラス名.create(カラム名1: 1, カラム名2: 2)
#上記の引数のハッシュは省略されてます。
#モデルのクラス名.create({ カラム名1: 値1, カラム名2: 値2})

そのため、createメソッドにストロングパラメータを指定することで、許可されたデータのみをデータベースに保存することができます。

employees_controller.rb
1
2
3
4
def create
  @employee = Employee.create(params.require(:employee).permit(:name, :department_id))
  # createメソッドの引数は、{"name"=>"西本知子", "department_id"=>"2"}になります。
end

このように、permitメソッドを使用すると、特定のキー(属性)のみを許可し、それ以外のキーは無視されます。これにより、許可されたキーに関連するデータのみが使用され、セキュリティが確保されます。

ストロングパラメータの実装手順

コントローラにストロングパラメータを実装する際には、privateメソッドとして定義することが一般的です。この方法により、定義したメソッドはコントローラ内部でのみ使用できます。

コントローラ名_controller.rb
1
2
3
4
5
6
7
8
9
10
class コントローラ名 < ApplicationController
  #その他のアクション

private
# ストロングパラメータの定義
def メソッド名
params.require(:モデル名).permit(:キー名1, :キー名2)
end
end

例えば、create アクションでemployee_params メソッドを呼び出してストロングパラメータを使用する方法は以下の通りです。

例 | employees_controller.rb
1
2
3
4
5
6
7
8
9
10
11
class EmployeesController < ApplicationController
  def create
@employee = Employee.create(employee_params)
end private def employee_params
params.require(:employee).permit(:name, :department_id)
end end

この方法を採用すると、先ほどのようにcreate メソッドの引数にストロングパラメータを指定した場合と同じ結果が得られます。

employees_controller.rb | create メソッドの引数にストロングパラメータを指定した場合
1
2
3
4
def create
  @employee = Employee.create(params.require(:employee).permit(:name, :department_id))
  # createメソッドの引数は、{"name"=>"西本知子", "department_id"=>"2"}になります。
end
ストロングパラメータを実装しましょう

employees_controller.rb ファイルを開き、private メソッドとしてストロングパラメータを定義します。そして、create メソッドの引数でこのメソッドを呼び出すように変更しましょう。

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class EmployeesController < ApplicationController
# ...中略

  def create
    # 新しい社員を登録する処理
@employee = Employee.create(employee_params)
end # ...中略 def destroy # 特定の社員を削除する処理 end
private
def employee_params
params.require(:employee).permit(:name, :birthday, :department_id)
end
end

さいごに

この章では、Railsを使用して新規登録画面を作成し、フォームからのデータをデータベースに保存する一連のプロセスを学びました。form_withを利用したフォームの作成方法や、データ送信の流れ、ストロングパラメータを使用した安全なデータの受け取り方法など、Railsアプリケーションでデータを作成する際の基本的なスキルを身につけることができました。

この記事のまとめ

  • newアクションは、新規登録画面の表示を担う
  • newアクションで、フォームに必要な初期状態を設定(空のインスタンスを生成)し、ユーザーが新規登録を行うための入力フォームを表示する
  • createアクションは、フォームの入力が完了した後のデータ処理を担う