すでにメンバーの場合は

無料会員登録

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

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

Pikawakaにログイン

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

データ更新画面の作成(Update)

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

はじめに

概要

この記事では、Ruby on Railsでデータの更新方法を学びます。Webアプリケーションでは、既存のデータを効率的に更新する機能が不可欠です。社員情報の編集画面の作成を通じて、Railsでデータをどのように更新し、その変更を画面に反映させるかを理解しましょう。

目標

この章の目標
  • 社員情報の編集画面の作成手順を理解し、実装できるようになる。
  • Railsにおけるデータの更新方法とその原則を把握する。
  • ユーザーが入力したデータの更新をWebブラウザを通じて効率的に行う一連の流れを学ぶ。
この章で完成するもの

この章では、既存の社員情報をデータベースで更新するための「データ更新画面」を実装します。この画面の主な目的は、一覧画面に表示される各社員の情報の詳細の隣にある「編集」リンクをクリックした際に、ユーザーが社員情報を変更して更新することです。

以下の画像は、社員情報を編集する画面の例です。
以前実装した社員登録画面と異なり、ユーザーが情報を編集しやすいように、現在の情報がフォームに事前に表示されるようにします。

この画面では、既存の社員情報を編集するためのフォームが中心となります。フォームの下部には「更新する」というボタンがあり、このボタンをクリックすることで変更されたデータがデータベースに保存されます。

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

それでは、社員情報の更新機能の実装に取り組みましょう!

ぴかわかさん

1. 更新のためのルートの確認

既存の社員情報を更新するためには、2つの重要なルートが必要です。

まずは、「既存の社員を編集するためのフォームを表示」するルートを設定し、次にそのフォームを使って「既存の社員の情報を更新」するためのルートを確立します。

社員情報の編集画面へのアクセス

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

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

以前、社員詳細画面の実装で学習しましたが、:idはプレースホルダーとして機能します。これは、実際のリクエストが行われたとき、具体的な値に置き換わる部分です。

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

現在、editアクションはまだ実装されていませんが、将来的にはリクエストから送られてくる値を使用して、データベースから編集する社員の情報を特定し、そのデータを編集フォームに表示する処理を行う予定です。

ここで重要なのは、このリクエストがデータの更新処理を行うのではなく、社員情報を編集するためのフォームを表示することです。

ぴっかちゃん

なるほど、社員情報の更新は、まず編集フォームを表示させるところから始まるんだね。

最初にGET /employees/:id/editで編集フォームを表示し、そこから変更したい社員の情報を入力していくんだ。

ぴかわかさん

社員情報の更新データの送信

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

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

社員情報の更新に関するルートを整理してみましょう。

最初に、GET /employees/:id/editというリクエストを送信してeditアクションで編集フォームを表示させます。

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

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

config/routes.rbファイルを開いて、既存の社員の編集画面を表示するためのeditアクションへのルートと、データを更新するためのupdateアクションへのルートが正しく設定されていることを確認してください。

この設定により、既存の社員の編集画面を表示するリクエストはemployeesコントローラのeditアクションに、データを更新するリクエストは、updateアクションに対応付けられます。

2. 編集ビューとリンクの作成

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

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

編集ビューの作成

既存の社員情報を編集するためのビューを作成しましょう。ここでは、edit アクションに対応するシンプルなビューを edit.html.erb に設定します。

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

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

app/views/employees/edit.html.erb
1
2
3
<h2>社員情報の編集</h2>

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

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

一覧画面への編集リンク追加

次に、一覧画面に社員情報の編集画面へ簡単にアクセスできる「編集」リンクを追加します。これにより、ユーザーは一覧画面から直接編集画面に移動できるようになります。

編集画面にアクセスするためには、GET /employees/:id/editというリクエストを送信する必要があります。:idには各社員のidの値(例では3)が入ります。

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

編集画面へのリンク
1
2
3
<% @employees.each do |employee| %>
<a href="/employees/<%= employee.id %>/edit">編集</a>
<% end %>

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

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

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

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

一覧画面に「編集」のリンクを追加しましょう

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

<table>
  <!-- テーブルのヘッダー -->
  <thead>
    <tr>
      <th>名前</th>
      <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>
<td><a href="/employees/<%= employee.id %>/edit">編集</a></td>
</tr> <% end %> </tbody> </table>
Webブラウザでリンクの動作を確認しましょう

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

リンクをクリックして、編集画面に遷移するかも確認しましょう。

これで、編集ビューの作成と一覧画面からのリンク追加が完了しました。

3.editアクションの実装

editアクションの主な目的は、データベースから特定の社員の情報を取得して、それを編集画面に表示することです。社員の一覧画面にある「編集」リンクをクリックしたら、その社員の現在の情報が入力フォームに表示されるようにします。

これを実現するためには、「どの社員の情報を編集するのか」を特定することが必要です。

具体的には、editアクションでは、編集する特定の社員の情報を取得する必要があります。一覧画面で「編集」リンクをクリックした際に渡される社員のidparams[:id]として受け取り、そのidを引数としてfindメソッドを使用します。

employees_controller.rb
1
2
3
def edit
  @employee = Employee.find(params[:id])
end

これにより、対象の社員の情報をデータベースから検索し、取得することができます。

検索された社員情報は@employeeに代入することで、後に編集フォームのビューで現在の社員情報の表示に使用できます。

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

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

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
8
class EmployeesController < ApplicationController
  # ... [中略] ...
  def edit
    # 既存の社員情報を編集するためのフォームを表示する処理
@employee = Employee.find(params[:id])
@departments = Department.all
end end

上記のEmployee.find(params[:id])では、編集する社員の情報を取得します。

さらに、@departments = Department.allの行では、社員が所属する部署の一覧を取得しています。これにより、編集画面で部署のセレクトボックスを表示することができるようになります。

4. 編集機能の実装とデータ更新処理

既存の社員情報を編集するためのフォームを実装します。ユーザーが情報を編集しやすいように、現在の情報がフォームに表示されるようにします。

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

社員情報の編集に必要なフォームを段階的に作成した後、そのデータを更新するためのupdateアクションを実装し、更新完了ページが表示されるようにします。

最初に、HTMLを使って基本的な編集フォームの作成方法を学びます。更新処理の実装が完了した後、form_withヘルパーを使用してフォームを実装する方法について説明します。

ぴかわかさん

更新データの送信とHTMLフォームの活用

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

既存の社員情報をデータベースで更新するためには、PATCH /employees/:idという形式のリクエストをWebブラウザから送信する必要があります。この際に使用するHTTPメソッドはPATCHです。

しかし、HTMLフォームではGETPOSTメソッドのみをサポートしているため、PATCHメソッドを直接使用して送信することはできません。

HTMLフォームは、以下のように<form>タグ内でmethod属性を用いてHTTPメソッドを指定しますが、選択できるのはGETPOSTのみです。

この制限を回避するために、Railsでは_methodという特別な隠しフィールドを使用して、PATCHDELETEなどのHTTPメソッドをPOSTメソッドを通じてエミュレート(模倣)することができます。

例えば、method="post"を設定してフォームをPOSTメソッドで送信する際、_method隠しフィールドにPATCHを設定すると、RailsはそのリクエストをPATCHリクエストとして扱います。

PATCHとして扱いたい場合
1
2
3
4
5
6
<form action="送信先URL" method="post">
  <!-- PATCHメソッドをエミュレート(模倣)するための隠しフィールド -->
<input type="hidden" name="_method" value="patch">
<!-- その他のフォーム要素 --> </form>

このようにして、別のHTTPメソッド(PUT、PATCH、DELETEなど)をPOSTメソッドを通じてエミュレート(模倣)することができます。

ぴっかちゃん

なるほど、HTMLフォームではPOSTメソッドを使用して送信し、隠しフィールドを使ってサーバーにこのリクエストをPATCHとして処理するよう指示しているんだね!

POSTメソッドを通じてPATHCメソッドを指定してみましょう

ここまで学習した内容を編集画面に反映させましょう。edit.html.erbファイルに以下のハイライトされる箇所を追加しましょう。action="送信先URL"は次で学習するので、一旦は以下のように記述してください。

app/views/employees/edit.html.erb
1
2
3
4
5
6
7
8
9
10
<h2>社員情報の編集</h2>

<form action="送信先URL" method="post" class="employee-form">
<!-- 認証トークン(authenticity token)を追加する -->
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<!-- PATCHメソッドを指定する -->
<input type="hidden" name="_method" value="patch">
</form>
<a href="/employees">社員情報一覧に戻る</a>

編集対象の社員情報を持つインスタンスの活用

既存の社員情報を更新するためには、PATCH /employees/:idという形式のリクエストをWebブラウザから送信する必要があります。以前、登録フォームを実装した際に、HTMLフォームではaction属性に送信先URLを指定することを学びました。

HTMLフォーム
1
2
3
<form action="送信先URL" method="HTTPメソッド">
  <!-- その他のフォーム要素 -->
</form>

今回は、先ほどeditアクションで実装した@employeeのインスタンス変数を利用して、送信先URLを動的に作成します。

@employeeには、以下のように編集する社員の情報が代入されています。

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
class EmployeesController < ApplicationController
  # ... [中略] ...
  def edit
@employee = Employee.find(params[:id])
@departments = Department.all end end

action属性では、/employees/の後に@employee.idを指定することで、送信先URLを動的に生成できます。この方法により、編集対象の社員が変わるごとに、フォームの送信先も適切に変更されます。

送信先URLを動的に作成
1
2
3
4
5
6
<form action="/employees/<%= @employee.id %>" method="post">
<!-- PATCHメソッドをエミュレート(模倣)するための隠しフィールド --> <input type="hidden" name="_method" value="patch"> <!-- その他のフォーム要素 --> </form>

例えば、一覧画面で社員IDが3の高橋さんの行の「編集」ボタンをクリックすると、GET /employees/3/editのリクエストが送信され、ルーティングの:idには3が代入されます。

この場合のeditアクションでは、params[:id]を用いて社員IDを取得します。したがって、以下のようにfindメソッドの引数には3が使用され、高橋さんの社員情報が@employeeに代入されます。

app/controllers/employees_controller.rb
1
2
3
4
5
def edit
  @employee = Employee.find(params[:id])
  # この例ではEmployee.find(3)となります。
  # ... [中略] ...
end

そして、action属性に/employees/<%= @employee.id %>と設定することで、送信先URLは/employees/3となります。これにより、更新データを適切なルートで送信することができます。

送信先URLを動的に作成
1
2
3
4
5
6
<form action="/employees/<%= @employee.id %>" method="post">
  <!-- PATCHメソッドをエミュレートするための隠しフィールド -->
  <input type="hidden" name="_method" value="patch">

  <!-- その他のフォーム要素 -->
</form>

編集フォームは、ユーザーが情報を編集しやすいように、現在の情報がフォームに表示されるようにします。この現在の情報は「value属性」を使用して入力欄に表示することができます。

社員の名前を表示する場合は、value属性に@employee.nameを設定します。

例 | 現在の情報をフォームに表示させる
1
2
3
<!-- 名前入力欄 -->
<label for="employee_name">名前:</label>
<input type="text" id="employee_name" name="employee[name]" value="<%= @employee.name %>">

このように設定することで、フォームを開いた時に既に社員の現在の名前が入力欄に表示され、ユーザーはそれを編集するだけで済むようになります。

ぴっかちゃん

value属性に事前に値を設定すると、フォームを開いたときにすでに情報が入力されているんだね!編集作業がスムーズになって良いね!

セレクトボックスの場合は、value属性ではなく、選択肢のoptionタグにselected属性を追加する必要があるよ!この辺は次で詳しく説明するね!

ぴかわかさん
編集画面のHTMLフォームを完成させましょう

ここまで学習した内容を編集画面に反映させましょう。edit.html.erbファイルに以下のハイライトされた箇所を変更・追加してください。また、action="送信先URL"も適切に変更することを忘れないようにしましょう。

app/views/employees/edit.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
<h2>社員情報の編集</h2>

<form action="/employees/<%= @employee.id %>" method="post" class="employee-form">
<!-- 認証トークン(authenticity token)を追加する --> <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>"> <!-- PATCHメソッドを指定する --> <input type="hidden" name="_method" value="patch">
<div class="form-group">
<label for="employee_name">名前:</label>
<input type="text" id="employee_name" name="employee[name]" value="<%= @employee.name %>">
</div>
<div class="form-group">
<label for="employee_birthday">生年月日:</label>
<input type="date" id="employee_birthday" name="employee[birthday]" value="<%= @employee.birthday %>">
</div>
<div class="form-group">
<label for="employee_department_id">部署:</label>
<select id="employee_department_id" name="employee[department_id]">
<% @departments.each do |department| %>
<option value="<%= department.id %>" <%= 'selected' if @employee.department_id == department.id %>>
<%= department.name %>
</option>
<% end %>
</select>
</div>
<div class="form-submit">
<input type="submit" value="更新する">
</div>
</form> <a href="/employees">社員情報一覧に戻る</a>

以下の部分は、@departmentsを使用して、社員の部署を選択するためのセレクトボックス内の各選択肢を生成しています。

HTMLフォーム | 社員の部署を選択するためのセレクトボックスを作成
1
2
3
4
5
6
7
8
<label for="employee_department_id">部署:</label>
<select id="employee_department_id" name="employee[department_id]">
<% @departments.each do |department| %>
<option value="<%= department.id %>" <%= 'selected' if @employee.department_id == department.id %>>
<%= department.name %>
</option>
<% end %>
</select>

デベロッパーツールで確認すると、以下の選択肢を生成します。

<option>タグ内のvalue属性は、その選択肢が選ばれた際にフォームが送信するデータの値を指定するものなので、他のフォーム要素とは異なり、value属性に値を設定しても、その選択肢がデフォルトで選択状態になるわけではありません。

選択状態にしたい場合は、その選択肢の<option>タグにselected属性を追加する必要があります。例えば、以下のように「営業」がselected属性を持っているため、この例では、セレクトボックスが表示されたときに「営業」がデフォルトで選択されます。

この動作は<%= 'selected' if @employee.department_id == department.id %>によって実現されています。

HTMLフォーム | 社員の部署を選択するためのセレクトボックスを作成
1
2
3
4
5
6
7
8
<label for="employee_department_id">部署:</label>
<select id="employee_department_id" name="employee[department_id]">
  <% @departments.each do |department| %>
<option value="<%= department.id %>" <%= 'selected' if @employee.department_id == department.id %>>
<%= department.name %> </option> <% end %> </select>

上記では、現在編集中の社員の部署id@employee.department_id)が選択肢の部署id(department.id)と一致する場合に、その選択肢にselected属性を動的に付与するための条件式です。

Webブラウザで編集画面を確認しましょう

サーバーを起動し、Webブラウザで/employees/7/editにアクセスするか(または一覧画面の「編集」リンクをクリックするか)して、以下のように編集画面が表示されることを確認しましょう。

updateアクションの実装とデータ更新処理

編集フォームから送信されたデータを処理するためのupdateアクションの実装方法を学びます。編集フォームは、ユーザーが既存の社員情報を変更するための画面を提供し、これらの変更はupdateアクションを通じてデータベースに反映されます。

データの更新には、ActiveRecordが提供するupdateメソッドを利用します。このメソッドを使用する前に、findメソッドなどで更新対象のオブジェクトを取得し、その後で更新処理を行います。

updateメソッドの引数には、以下のように更新したいプロパティ名とその値をハッシュ形式で指定します。

更新対象のオブジェクトのプロパティを引数の値に更新する
1
更新対象のオブジェクト.update(プロパティ名: )

例えば、ユーザー名 '田中太郎''田中航太郎' に更新する場合、まず更新対象のオブジェクトを取得し、次に update メソッドの引数で更新したい情報を指定します。

updateメソッドを利用して更新処理を行う場合
1
2
user = User.find(1)
user.update(name: '田中航太郎')

上記のUser.find(1)では、以下のように更新対象のオブジェクト(この場合、田中太郎さんの情報)を取得します。

そして、取得した更新対象のオブジェクトに対してupdateメソッドを呼び出すと、指定されたプロパティは引数の値(この場合はname: '田中航太郎')に更新され、その変更はデータベースに保存されます。

それでは、updateメソッドを利用して更新処理を行いましょう。

ぴかわかさん
updateアクションに更新処理を実装しましょう

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

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

  def update
    # 既存の社員情報を更新する処理
@employee = Employee.find(params[:id])
@employee.update(employee_params)
end def destroy # 特定の社員を削除する処理 end private def employee_params params.require(:employee).permit(:name, :birthday, :department_id) end end

上記のEmployee.find(params[:id])では、更新する社員の情報を取得します。

次の@employee.update(employee_params)の行では、ストロングパラメータを使用して、その社員のデータを更新します。

更新完了の画面を作成しましょう

更新処理が完了した後には、ユーザーに更新が成功したことを伝えるために、更新完了のメッセージを表示します。update.html.erbファイルを作成し、以下のコードを追加しましょう。

app/views/employees/update.html.erb
1
2
3
4
5
<h2>更新完了</h2>

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

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

上記によって、更新完了のメッセージと更新された社員の名前が更新完了ページに表示されます。

社員の情報を更新してみましょう

編集フォームで「西本知子」さんの部署を「営業」から「開発」に更新してみます。

以下のように部署を変更後、更新ボタンをクリックしましょう。

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

一覧画面でも以下のように西本知子さんの部署が「営業」から「開発」に更新されていることが確認できます。

Pryコンソールで更新処理の流れを確認してみましょう

まず、updateアクション内にbinding.pryを挿入します。

app/controllers/employees_controller.rb
1
2
3
4
5
6
7
8
9
10
11
class EmployeesController < ApplicationController
# ...中略

  def update
    # 既存の社員情報を更新する処理
binding.pry
@employee = Employee.find(params[:id]) @employee.update(employee_params) end # ...中略 end

次にWebブラウザで/employees/7/editにアクセスするか(または一覧画面の「編集」リンクをクリックするか)して、以下のように西本知子さんの編集画面を表示しましょう。

続いて、西本知子さんの部署を「開発」から「営業」に変更し、更新ボタンをクリックしましょう。

このとき、rails sで起動したサーバーのコンソールを確認すると、Pryプロンプトが表示されます。以下のようにparams[:id]を実行し、西本知子さんのid7を取得していることを確認しましょう。

上記の確認によって、updateアクションの以下の行で更新対象の社員情報を取得し、@employeeに代入していることが理解できます。

app/controllers/employees_controller.rb
1
2
3
4
5
def update
  # 指定されたidを持つ社員をデータベースから探し、@employeeに代入
@employee = Employee.find(params[:id])
@employee.update(employee_params) end

次に、Pryコンソールで以下を実行しましょう。

Pryコンソール
1
params.require(:employee).permit(:name, :birthday, :department_id)

上記の操作を行うと、以下のように編集フォームから送信されたデータを取得できます。部署の場合、開発が1、営業が2ですので、department_id:2であることから、営業部門への変更であることがわかります。

つまり、updateアクションでストロングパラメータを使用する箇所において、@employee.updateの引数であるemployee_paramsには、{"name"=>"西本知子", "birthday"=>"1974-10-23", "department_id"=>"2"}が渡され、これに基づいて更新が行われます。

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

  def update
    @employee = Employee.find(params[:id])
    # @employeeに対してupdateメソッドを呼び出し、employee_paramsの値で更新
    # 例では@employee.update({"name"=>"西本知子", "birthday"=>"1974-10-23", "department_id"=>"2"})になる
@employee.update(employee_params)
end # ...中略 private
def employee_params
params.require(:employee).permit(:name, :birthday, :department_id)
end
end

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

app/controllers/employees_controller.rb | binding.pryを削除する
1
2
3
4
5
6
7
8
9
10
class EmployeesController < ApplicationController
# ...中略

  def update
    # 既存の社員情報を更新する処理
    @employee = Employee.find(params[:id])
    @employee.update(employee_params)
  end
# ...中略
end

一覧画面で確認すると、西本知子さんの部署は「開発」から「営業」に更新されていることが確認できます。

これで更新処理を確認する作業は完了です。

form_withによる編集フォームの実装

新規登録フォームの作成時にform_withを学習しましたが、form_withメソッドでmodel引数を使用すると、「インスタンスの状態」に基づき、適切なアクションのURLとHTTPメソッドが自動的に設定されます。

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

新規登録フォームでは、データベースに保存されていない新規のオブジェクトが@employeeに代入されていました。

新規登録フォームの場合
1
2
3
def new
  @employee = Employee.new # Employeeの新しい空のインスタンスを生成
end

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

今回、編集フォームを表示するeditアクションでは、@employeeにはすでにデータベースに保存されているオブジェクト(編集する特定の社員)が代入されています。

編集フォームの場合
1
2
3
4
def edit
@employee = Employee.find(params[:id])
# ... [中略] ... end

そのため、editアクションに対応する編集ビュー(edit.html.erb)でform_withメソッドを使用し、model引数に@employeeを指定すると、フォームの送信先URLはupdateアクションに設定されます。使用するHTTPメソッドはPOSTになり、隠しフィールドが作成されてPATCHメソッドとして扱われるように自動で設定されます。

以下は、form_withメソッドを使用した場合に表示される編集フォームの例です。

このようにmodel引数に渡されるインスタンスの状態によって、form_withの挙動が自動的に調整されます。このため、同じフォームのコードを使用しても、異なるシナリオ(新規作成と編集)で異なる結果が得られることになります。

form_withを使用して編集フォームを実装しましょう

ルーティングの設定を変更しましょう

新規登録では、ヘルパーパスが自動的に生成されていましたが、編集の場合は自動生成されません。そのため、ルーティングにas: :employeeを追加しましょう。

config/routes.rb
1
2
3
4
Rails.application.routes.draw do
  # ... [中略] ...
patch 'employees/:id', to: 'employees#update', as: :employee
end

ルーティングを変更した後は、Railsサーバーを再起動してください。

as: :employeeを追加することで、form_withでの送信先URLが正しく設定されるようになります。ヘルパーパスについては後の章で詳しく解説します。

form_withを使用して編集フォームを実装しましょう

edit.html.erbファイル内でのHTMLフォームをform_withを使用した形に変更します。以下のように編集しましょう。

app/views/employees/edit.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>
Webブラウザで編集画面を確認しましょう

サーバーを起動し、Webブラウザで/employees/7/editにアクセスするか(または一覧画面の「編集」リンクをクリックするか)して、以下のように編集画面が表示されることを確認しましょう。

デベロッパーツールで確認すると、以下の通りform_withによって送信先URLやHTTPメソッド、隠しフィールドが更新用のルートに適切に設定されていることがわかります。

これでform_withによる編集フォームの実装は完了しました。

ポイント

form_withでは、インスタンスの状態(新規作成または既存のレコードの更新)に基づいて、適切なアクションのURL(新規作成の場合はcreateアクション、更新の場合はupdateアクションへのURL)とHTTPメソッド(新規作成の場合はPOST、更新の場合はPATCH)が自動で設定される。

さいごに

本記事を通じて、社員情報の編集と更新という、Webアプリケーションでのデータの更新方法の基本について学びました。社員情報の編集画面の作成から、実際にデータを更新する一連の流れを理解することで、ユーザーにとって使いやすく、直感的な情報の更新方法を提供できるようになります。

この記事のまとめ

  • 編集フォームでは、ユーザーが情報を編集しやすいように、現在の情報がフォームに事前に表示されるようにする
  • editアクションで編集フォームを表示させる
  • updateアクションで社員情報を更新する処理を行う