はじめに
概要
この記事では、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
に設定します。
app/views/employees
ディレクトリにnew.html.erb
ファイルを作成し、以下のコードを記述してください。
1
2
3
<h2>新規社員登録</h2>
<a href="/employees">社員情報一覧に戻る</a>
サーバーを起動し、Webブラウザで/employees/new
にアクセスして、以下のように新規登録画面が表示されることを確認しましょう。
一覧画面へのリンク追加
次に、一覧画面に新規登録画面へ簡単にアクセスできる「新規作成」リンクを追加します。これにより、ユーザーは一覧画面から直接新規登録画面に移動できるようになります。
新規登録画面にアクセスするためには、GET /employees/new
というリクエストを送信する必要があります。
このリクエストは、a
タグにhref="/employees/new"
を指定することで、GETメソッドによるリクエストとして簡単に送信できます。
1
<a href="/employees/new">新規作成</a>
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
ファイルに以下のスタイルを追加します。
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ブラウザで/employees
にアクセスしてみましょう。一覧画面に「新規作成」リンクが表示されていることを確認します。
リンクをクリックして、新規登録画面に遷移するかも確認しましょう。
これで、新規登録ビューの作成と一覧画面からのリンク追加が完了しました。次のセクションでは、フォームの実装とデータの送信について学んでいきます。
3. データ入力フォームの基本と送信
新規社員の登録に必要なフォームを段階的に作成し、データの送信方法を学びます。まずは、HTMLでのフォームの基本的な作り方から始めます。その後、Railsのform_with
ヘルパーを利用して、より高度なフォームを実装する方法について学びます。
以下の画像のように、新規登録フォームが表示されることを目指します。
HTTPメソッドの復習
HTMLフォームの基礎に入る前にGET
やPOST
のHTTPメソッドを振り返ります。
新規社員の情報をデータベースに登録するには、WebブラウザからPOST /employees
へのリクエスト送信が必要でしたね。
これまでに学んだように、GET
メソッドは、主にサーバーから情報を取得するためのリクエストを行う(Webページの閲覧など)際に使用します。Webページ上のリンク(<a>
タグ)をクリックすると、自動的にGET
リクエストがサーバーに送信されます。
1
<a href="https://example.com/page.html">プログラミングについて徹底解説!</a>
一方で、POST
メソッドはサーバーに情報を送信する際に使用します。新規登録やログインなど、機密性の高い情報を扱う場合に適しています。POSTリクエストを送信する方法はいくつかありますが、その中でも最も一般的なのはHTMLフォームを使用したものです。
HTMLフォームは、以下のように<form>
タグを使って定義されます。このタグ内でmethod
属性を使用して、HTTPメソッドを指定します。
1
2
3
4
5
6
7
8
9
<!-- GETメソッドでフォームを送信する例 -->
<form action="/search" method="get">
<!-- フォーム要素 -->
</form>
<!-- POSTメソッドでフォームを送信する例 -->
<form action="/submit" method="post">
<!-- フォーム要素 -->
</form>
HTMLフォームはGET
とPOST
のどちらのメソッドでも利用できますが、新規登録やログインなど機密性の高い情報を扱う際は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]
のようにネストされた形式で使用することで、サーバー側でデータを受け取る際に、データがネストされたハッシュの形で整理されます。これにより、複雑なデータ構造を扱う場合に、データを整理しやすくなります。
1
2
<input type="text" name="employee[name]">
<input type="date" name="employee[birthday]">
上記のようにname
属性をネストされた形式で使用すると、関連するすべてのデータがparams
オブジェクト内のemployee
キー下に格納されます。
このようにname
属性をネストされた形式で使用すると、params
内で情報が整理されます。この方法は、フォームから送信されたデータの構造を整理しやすくし、関連するデータを一括で扱いやすくするために役立ちます。
たとえば、Railsのコントローラのアクションでは、params[:employee]
を使用して、employee
キーの下にネストされたデータに一括でアクセスできます。
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
ファイルの以下のハイライトされる部分を追加してください。
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
ファイルに以下のスタイルを追加してください。
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ブラウザで/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を用いて実際に確認します。フォームから送信されたデータがサーバーでどのように処理され、アクセスされるかを確かめることで、理論的な理解を実践的な知識に深めます。
新規登録画面で社員情報を入力し「登録する」ボタンをクリックすると、入力したデータを含むPOST /employees
リクエストがサーバーに送信され、employees
コントローラのcreate
アクションで処理されます。
フォームから送信されたデータを確認するために、employees_controller.rb
ファイル内のcreate
アクションにブレークポイントを設定します。このブレークポイントを設定することで、プログラムの実行を一時停止し、送信されたパラメータを確認することが可能になります。
以下のコードのように、binding.pry
をcreate
アクション内に追加してください。
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
属性に設定されます。この値は、リクエスト送信時に他のフォームデータと共にサーバーに送信されます。
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アプリケーションから送信されたものであることを保証するためのセキュリティ対策です。
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
属性がどのように機能しているかを理解することができましたね。
最後に、Pryコンソールからexit
コマンドで抜け出し、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メソッドを指定していました。さらに、認証トークンも手動でフォームに追加していました。
1
2
3
4
<form action="/employees" method="post">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<!-- フォーム要素 -->
</form>
上記のHTMLフォームは、Railsの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.new
はEmployee
の新しい空のインスタンスを生成します。このインスタンスではid
などの値はnil
となります。
このように生成されたインスタンスは、まだデータベースに保存されていない新規のオブジェクトです。この新しいインスタンスが@employee
に代入されている場合、Railsはこのインスタンスを新規作成用として認識します。
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
の直前までが引数として扱われます。
1
2
3
<%= form_with model: @employee, local: true do |f| %>
<!-- フォーム要素 -->
<% end %>
RailsはRubyで書かれているんだよね。Rubyって引数の省略形をよく使うんだって聞いたことがあるよ。
その通りだよ。Rubyではこのような引数の括弧を省略することが一般的だよ。説明では括弧を使ってわかりやすくするけど、実際にアプリケーションに実装する際には、省略形で記述するよ。
学んだ内容をアプリケーションに適用する
まず、new
アクションでEmployee
モデルの新しい空のインスタンスを作成し、@employee
に代入します。これにより、form_with
メソッドは@employee
を新規登録フォーム用のインスタンスとして認識します。
new
アクション内に、以下のハイライトされた行を追加してください。
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はこれを新規登録用のフォームとして扱います。
new.html.erb
ファイル内でのフォームをform_with
を使用した形に変更します。これまでの<form>
タグをform_with
メソッドで置き換えます。
ここまで学習した内容だけを変更します。
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
を使用する場合、認証トークンは自動的に生成されるため、手動で追加する必要はありません。このため、認証トークンに関するコード行は削除しましょう。
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_field
やf.date_field
を使って、それぞれテキスト入力欄や日付入力欄を生成することが可能です。
1
2
3
4
<%= form_with(model: モデルオブジェクト, local: true) do |f| %>
<%= f.text_field :属性名 %><!-- 指定する属性に紐付くテキスト入力欄 -->
<%= f.date_field :属性名 %> <!-- 指定する属性に紐付く日付入力欄 -->
<% end %>
:属性名とは
次に、フィールドタイプの後に指定される:属性名
を確認していきましょう。
:属性名
は、フォームフィールド(例えば日付入力欄など、ユーザーがデータを入力するための特定の領域)がモデルのどの属性に対応しているかを指定します。モデルの属性は、Railsのモデルで表されるデータベーステーブルのカラムに対応しています。
たとえば、Employee.new
を実行すると、id
やname
、birthday
などが表示されるのは、これらがEmployee
モデルの属性だからです。
次に、@employee
変数にEmployee
モデルの新しい空のインスタンスが代入されている場合を考えてみましょう。この状況でform_with
を使用し、f.date_field :birthday
と記述すると、この日付入力欄はEmployee
モデルのbirthday
属性と紐づけられます。
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フォームに書き換えた例です。
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
メソッドを使用することで、モデルの属性に対応するラベルを生成し、紐づけることができます。
1
2
<%= f.label :birthday, '生年月日:' %> <!-- 生年月日入力欄のラベル -->
<%= f.date_field :birthday %> <!-- 生年月日入力フィールド -->
form_with
では、ラベルと入力フィールドの属性を同じモデルの属性にすることで、ラベルとフォームフィールドが自動的にモデルの属性と紐付けられます。
form_withでフォーム要素の実装
new.html.erb
ファイル内でのフォーム要素をform_withを使用した形に変更します。
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.label
とf.text_field
(または他のフォームフィールドヘルパー)を使用する際に、明示的にid
属性を指定する必要はありません。
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ブラウザで/employees/new
にアクセスしてみましょう。このとき、rails s
でサーバーを起動させることを忘れないでください。
アクセスすると、以下の画像のようにHTMLフォームで実装した時と同様の社員登録フォームが確認できます。
以上でform_with
によるデータ入力フォームの実装は完了です。
5.フォームデータのデータベース保存の検証
createアクションの実装に入る前に、登録フォームからのデータでデータベースに保存ができるかをPryコンソールを使用して確かめてみましょう。
新規登録画面で社員情報を入力し「登録する」ボタンをクリックすると、入力したデータを含むPOST /employees
リクエストがサーバーに送信され、employees
コントローラのcreate
アクションで処理されます。
フォームから送信されたデータを確認するために、employees_controller.rb
ファイル内のcreate
アクションにブレークポイントを設定します。
以下のコードのように、binding.pry
をcreate
アクション内に追加してください。
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
を実行してみましょう。すると、name
やbirthday
以外にもid
、created_at
、updated_at
などの属性がありますが、これらは保存の際に自動的に設定されるため、新しいインスタンス作成時にはnil
になっています。
しかし、department_id
は有効な値が設定されていないと、保存は失敗します。
解決策としては、フォームに部署の選択肢を追加し、適切なdepartment_id
を含むようにする必要があります。これにより、フォームからのデータが正しくデータベースに保存されるようになります。
最後に、Pryコンソールからexit
コマンドで抜け出し、binding.pryを削除しておきましょう。
1
2
3
4
5
class EmployeesController < ApplicationController
# ...中略
def create
# 新しい社員を登録する処理
end
これで、Pry-Railsを利用したデータベース保存の検証作業を完了しました。
新規社員登録フォームに部署選択を追加
社員登録フォームに部署選択の機能を追加します。これにより、社員が所属する部署もフォームから選べるようになります。
まず、Employee
モデルと関連するDepartment
モデルのデータをフォームで使用できるようにします。employees_controller.rb
に必要なコードを追加します。
以下のコードをnew
アクションに追加してください。
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
ヘルパーでは、collection_select
を使用してセレクトボックスを作成することができます。
1
2
3
<%= form_with model: @employee, local: true do |f| %>
<%= f.collection_select :属性名, コレクション, 値の方法, テキストの方法 %>
<% end %>
今回の部署を選択できるセレクトボックスの場合は、以下のように指定します。
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
属性の値(例えば1
や2
など)を指します。
この:id
は、セレクトボックスの各選択肢に対応する値(value属性)として使われ、ユーザーがセレクトボックスから部署を選択した際に、その部署のid
がEmployee
モデルのdepartment_id
属性に保存されます。これにより、Employee
モデルのインスタンスは選択された部署に関連付けられます。
最後は「テキストの方法」です。
ここで指定される:id
は、Department
モデルの各インスタンスのname
属性の値(例えば開発
や営業
など)を指します。
この:name
は、セレクトボックスに表示される各選択肢の表示テキストとして部署の名前が使用されます。これにより、ユーザーは部署の名前を見て選択を行うことができます。
したがって、ユーザーがセレクトボックスで部署を選択すると、その部署のid
がdepartment_id
属性としてEmployee
モデルのインスタンスに割り当てられ、部署のname
がユーザーに表示される選択肢として機能します。
例えば、セレクトボックスで「開発」を選択した際には、department_id
に1
が関連付けられます。
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
に以下のスタイルを追加します。
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.rb
のcreate
アクションにbinding.pry
を追加し、フォームから送信されたデータが正しく処理されるか確認します。
以下のコードのように、binding.pry
をcreate
アクション内に追加してください。
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]
を続けて実行してみましょう。
すると、登録フォームでセレクトボックスから選択した営業が表示されていますね。
最後に、Pryコンソールからexit
コマンドで抜け出し、binding.pryを削除しておきましょう。
1
2
3
4
5
class EmployeesController < ApplicationController
# ...中略
def create
# 新しい社員を登録する処理
end
一覧画面と詳細画面への部署表示の追加
最後に、社員一覧画面と詳細画面にも部署情報を表示しましょう。
以前、アソシエーションでEmployee
モデルとDepartment
モデルの関連付けを行いました。これにより、Employee
モデルを介してDepartment
モデルの情報を簡単に取得できるようになりました。
1
2
3
4
class Employee < ApplicationRecord
belongs_to :department
validates :name, presence: true, length: { maximum: 30 }
end
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
ファイルを開いて、以下のハイライトされる箇所を追加しましょう。
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
ファイルを開いて、以下のハイライトされる箇所を追加しましょう。
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
テーブルにデータを保存する場合、以下のように指定します。
1
Employee.create(name: 値, birthday: 値, department_id: 値)
新規登録フォームに「西本知子」と「1974/10/23」が入力され、部署が「営業」に設定されたとしましょう。
登録フォームに入力されたデータは、create
アクションでparams
を介して取得できます。各入力欄の値は、params[:employee][:name]
、params[:employee][:birthday]
、params[:employee][:department_id]
を使用してアクセスできます。
データベースにデータを保存する際、createメソッドを使用して以下のように記述します。
1
2
3
4
Employee.create(
name: params[:employee][:name],
birthday: params[:employee][:birthday],
department_id: params[:employee][:department_id])
この場合、以下のように「西本知子」、「1974-10-23」、「2(営業)」として保存されます。
1
2
3
4
5
Employee.create(
name: "西本知子",
birthday: "1974-10-23",
department_id: 2
)
この処理をcreateアクションに記述し、@employee
に代入して、createアクションに対応するビューで使用できるようにします。
create
アクションでは、Employee
モデルを使用してフォームのデータをデータベースに保存します。params
を使用して各フィールドの値にアクセスし、Employee.create
で新しいレコードを作成します。
app/controllers/employees_controller.rb
を開いて、以下のようにcreate
アクションを編集してください。
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
ファイルを以下のように編集し、登録完了のメッセージと新規登録された社員の名前が登録完了ページに表示され、社員情報一覧へのリンクを追加します。
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)
ついて考えてみましょう。
1
params.require(:employee)
上記の指定は、リクエストされたパラメータの中に :employee
というキーが必ず存在していることを要求しています。もし :employee
キーがリクエストのパラメータに存在しない場合、Railsはエラーを発生させます。
require
メソッドを利用することにより、期待されるキー(例えば、特定のモデルに関連するパラメータ)がリクエストに含まれていることを保証できます。
permitメソッドとは
permit(:キー名)
は、params.require(:モデル名)
で指定されたモデルのパラメータの中で特定のキーを許可するための設定です。これにより、許可されたキーのデータのみがコントローラのアクションで使用できるようになります。
例えば、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)」として選択した場合、返り値は以下のようになります。
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メソッドにストロングパラメータを指定することで、許可されたデータのみをデータベースに保存することができます。
1
2
3
4
def create
@employee = Employee.create(params.require(:employee).permit(:name, :department_id))
# createメソッドの引数は、{"name"=>"西本知子", "department_id"=>"2"}になります。
end
このように、permit
メソッドを使用すると、特定のキー(属性)のみを許可し、それ以外のキーは無視されます。これにより、許可されたキーに関連するデータのみが使用され、セキュリティが確保されます。
ストロングパラメータの実装手順
コントローラにストロングパラメータを実装する際には、private
メソッドとして定義することが一般的です。この方法により、定義したメソッドはコントローラ内部でのみ使用できます。
1
2
3
4
5
6
7
8
9
10
class コントローラ名 < ApplicationController
#その他のアクション
private
# ストロングパラメータの定義
def メソッド名
params.require(:モデル名).permit(:キー名1, :キー名2)
end
end
例えば、create アクションでemployee_params
メソッドを呼び出してストロングパラメータを使用する方法は以下の通りです。
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
メソッドの引数にストロングパラメータを指定した場合と同じ結果が得られます。
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
メソッドの引数でこのメソッドを呼び出すように変更しましょう。
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アクションは、フォームの入力が完了した後のデータ処理を担う
この記事で学んだことをTwitterに投稿して、アウトプットしよう!
Twitterの投稿画面に遷移します