データベースに登録したデータの内容を変更する機能や画面は、どんなシステムでもほぼ必ず存在します。
今回はDBのデータを変更する方法を解説します。
SQL文でいうところの「UPDATE」ですね。
また登録画面と編集画面のビューを共通で使う方法も合わせて紹介します。
登録と編集のビューを別々に用意する方が、最初は分かりやすいと思います。
しかし、共通化しておくメリットが重々にあります。
例えば、登録する項目が増えた場合、登録と編集のビューを共通化しておくと「一つのビューファイル」を弄るだけで済みます。一方、登録と編集でビューを分けてしまうと「二つのビューファイル」を弄ることになります。
作成者と修正者が同じなら問題ないかもしれませんが、作成者と修正者が別々だった修正者はソースがどんな作りになっているか分かっていません。
場合によっては、登録のビューファイルだけ更新して、編集のビューファイルの更新をしなかった、なんてことになりかねません。
しかしビューを共通化しておくと、そのような危険を回避できて、バグを生む可能性も減るので、プログラマー的に望ましいソースになります。
そこで今回の記事では
- データの更新する画面の作り方
- 登録画面と編集画面のビューを共通で使う作り方
を解説します。
Laravelを活用してプログラムを作成する際に、必ず必要になってくる知識であり、今後役立つこと間違いありません。
ぜひ最後までお読みください!
今回使用するテーブル
名前 | タイプ | その他設定 |
id | int | 主キー |
login_id | varchar(50) | ユニーク |
password | varchar | – |
created_at | timestamp | – |
updated_at | timestamp | – |
テーブルの作成は入門編3を参考にしてください。
また、以下の記事で登録画面を作成して、いくつかデータの登録も行ってくださいね。
今回活用するファイル
今まで入門編を解説してきた中で、下記のファイルを利用するので用意をお願いします。
このブログの入門編を順番に行っている場合は、用意不要です。
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
// 2023.02.18 追記
Route::get('/hello', 'App\Http\Controllers\HelloController@index');
// 2023.03.11 追記
Route::get('/register_manager', 'App\Http\Controllers\ManagerController@index');
Route::post('/register_manager', 'App\Http\Controllers\ManagerController@register');
// 2023.03.25 追記
Route::get('/list_manager', 'App\Http\Controllers\ManagerController@list');
// 2023.04.01 追記
Route::DELETE('/list_manager', 'App\Http\Controllers\ManagerController@delete');
一覧画面に編集ボタンを配置する
はじめに、一覧画面に編集ボタンを配置するようにビューファイルを編集していきましょう!
手順1:ビューファイルを編集する
「Laravel入門6」で作成した一覧を表示するビューファイル「list_manager.blade.php」を編集します。
各ログインIDの横に編集ボタンを設置するようにします。
以下のようにソースを変更しましょう!
<h2>管理者一覧</h2>
<table>
@foreach ($Manager_List as $Manager)
<tr>
<td>{{ $Manager->login_id }}</td>
<!-- 編集ボタンを追加 ここから -->
<td>
<form action="{{ url('edit_manager/'.$Manager->id) }}" method="get">
<button type="submit">編集</button>
</form>
</td>
<!-- 編集ボタンを追加 ここまで -->
<!-- 削除ボタンを追加 ここから -->
<td>
<form action="{{ url('list_manager') }}" method="POST">
@csrf
@method('DELETE')
<input type="hidden" name="login_id" value="{{ $Manager->login_id }}"/>
<button type="submit">削除</button>
</form>
</td>
<!-- 削除ボタンを追加 ここまで -->
</tr>
@endforeach
</table>
追記したのは以下の部分ですね。
<!-- 編集ボタンを追加 ここから -->
<td>
<form action="{{ url('edit_manager/'.$Manager->id) }}" method="get">
<button type="submit">編集</button>
</form>
</td>
<!-- 編集ボタンを追加 ここまで -->
「編集したいデータのID」をGETで編集画面に送るようにしています。
手順2:一旦、ブラウザで確認する
ここまでで一覧画面のビューファイルの編集は終わりましたので、一旦ブラウザで「http://localhost/test-laravel/public/list_manager」にアクセスして表示に問題がないか確認してみましょう!
上記のように「managers」テーブルに登録されているIDの横に、編集ボタンが表示されましたか?
表示されれば、ここまでの作業に問題はありません!
人によって登録したIDは異なります。
phpMyadminで「managers」テーブルに登録されているデータと見比べてみてくださいね。
ルーティングの設定ファイルを編集する
では次に、ルーティングの設定ファイルを編集しましょう!
一覧から編集画面「edit_manager」へ遷移する処理を以下のように追記します。
Route::get('/edit_manager/{id}', 'App\Http\Controllers\ManagerController@edit');
「Route::get」にします。
前述でHTTPメソッドを「get」リクエストにしているからです。
コントローラーファイルを編集する
では次にコントローラーファイルを編集します。
「ManagerController.php」に以下のソースを追記します。
public function edit(Request $request)
{
$Manager_Date = Manager::where('id', $request->id)->first();
return view('edit_manager', compact('Manager_Date'));
}
一覧画面の編集ボタンを押した時に送ったデータは「編集したいデータのID」でしたね。
そのため1行目では「編集したいデータのID」のデータをDBに検索して受け取る処理を書きました。
2行目は編集画面のビューを表示させるよう指示をしています。
次に、編集と登録のビューを共通で使いたいので、ついでに登録関連のソースも少し編集します。
class ManagerController extends Controller
{
public function __construct(Manager $Manager) {
$this->Manager_Date = $Manager;
}
public function index()
{
$Manager_Date = $this->Manager_Date;
return view('register_manager', compact('Manager_Date'));
}
public function register(Request $request)
{
// バリデーションの記述追加
$request->validate([
'login_id' => ['required','unique:managers'],
'password' =>['required'],
]);
Manager::create([
"login_id" => $request->login_id,
"password" => $request->password,
]);
$message = "登録が完了しました。";
$Manager_Date = $this->Manager_Date;
return view('register_manager', compact('message','Manager_Date'));
}
<!-- 以下略 -->
登録関連も編集時と同じように「Manager_Date」をビューに渡さないと、エラーになってしまうので編集しました。
また「public function __construct(Manager $Manager)」も新しく用意します。
コンストラクタは、クラスからインスタンスを生成した時(オブジェクトがnewによって作成されたとき)に自動的に呼び出されるメソッドです。
ビューファイルを作成、編集する
次にビューファイルを作成したり、すでに作られたビューファイルを編集したりしていきます!
手順1:共通フォームパーツのビューファイルを作成する
今回は登録画面と編集画面を共通にしたいので、まずは「共通フォームパーツ」のビューファイルを作成します。
すでに作ってあった登録画面のビューファイル「register_manager.blade.php」から、テキストボックスなどのformタグ内部をコピーして貼り付けてください!
ログインID:<br>
<input type="text" name="login_id" value="{{ old('login_id') }}"><br>
@if($errors->has('login_id'))
@foreach($errors->get('login_id') as $message)
{{ $message }}<br>
@endforeach
@endif
パスワード:<br>
<input type="password" name="password"><br>
@if($errors->has('password'))
{{ $errors->first('password') }}<br>
@endif
また、次に以下の修正を行います。
<input type="text" name="login_id" value="{{ old('login_id', $Manager_Date->login_id) }}"><br>
修正したのは「 value=”{{ old(‘login_id’, $Manager_Date->login_id) }} 」の部分ですね。
この画面に表示された時、まず入力値があれば表示する「old()の第一引数」、次に入力値がなければ取得したデータを表示する「old()の第二引数」、と指示を出してます。
手順2:登録画面のビューファイルを編集する
次に登録画面のビューファイルを少しいじります。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>管理者登録フォーム</h2>
@if ($errors->any())
エラーがあるので確認してください。
@endif
@if(isset( $message ))
{{ $message }}
@endif
<form action="{{ url('/register_manager') }}" method="POST">
{{ csrf_field() }}
<!-- 共通フォームパーツ読み出し -->
@include('form-manager')
<input type="submit" value="送信">
</form>
</body>
</html>
先ほど作った「共通フォームパーツ」のビューファイルにコピーした部分を丸々削除して、以下のソースを付け足しました。
<!-- 共通フォームパーツ読み出し -->
@include('form-manager')
これで、先ほど作成した「共通フォームパーツ」のビューファイルを呼び出すことができます。
手順3:登録画面をブラウザで確認する
ここまでで、一旦ブラウザで「http://localhost/test-laravel/public/register_manager」にアクセスして、エラーにならないか確認してみてください。
適当にデータを登録してみて、エラーがでなければ登録画面はOKです!
手順4:編集画面のビューファイルを作成する
次にいよいよ編集画面のビューファイルを作成していきます。
ファイル名「edit_manager.blade.php」でビューファイルを作成して、以下のソースを記述しましょう!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>管理者更新フォーム</h2>
@if ($errors->any())
エラーがあるので確認してください。
@endif
@if(isset( $message ))
{{ $message }}
@endif
<form action="{{ url('/edit_manager') }}" method="POST">
<input type="hidden" name="id" value="{{ old('id', $Manager_Date->id) }}"/>
{{ csrf_field() }}
@method('PUT')
<!-- 共通フォームパーツ読み出し -->
@include('form-manager')
<input type="submit" value="送信">
</form>
</body>
</html>
登録画面のビューファイルとほとんど変わりませんね。
変わっているのは、以下の4箇所です。
- h2タグ内のタイトル
- formタグのアクション(action)先
- formのメソッド(method)をLaravel風に指定
- IDのデータを渡すinputタグ
該当のソースは以下のとおりです。
<h2>管理者更新フォーム</h2>
<form action="{{ url('/edit_manager') }}" method="POST">
@method('PUT')
<input type="hidden" name="id" value="{{ old('id', $Manager_Date->id) }}"/>
formタグのアクション先は登録のときとは別のものにしましょう!
「@method(‘PUT’)」はmethodをpostからputに上書き変更してあげるソースです。
前回の記事でも解説したのですが、「@method」ではHTTPメソッドを指定できます。
HTTPメソッドとは、
クライアントがサーバーにしてほしいことを依頼する手段で、主に以下の4つを使います。
「GET」:データを取得するときに利用する
「POST」:サーバーにデータを送信するときに利用する(主に新規登録の時)
「PUT」:サーバーにデータを送信するときに利用する(主に更新の時)
「DELETE」:既存データを削除したいときに利用する
今回使いたいのは「PUT」ですね!
しかし、<form>(フォームタグ)のmethodでは、「POST」か「GET」しか指定できません。
<form>のmethodに「PUT」を記述するとエラーになるので注意しましょう!
そこで、Laravelの「@method」を用いてPUTを指定します。
手順5:編集画面をブラウザで確認する
一旦ここでエラーが起こっていないか、画面を確認しましょう!
「http://localhost/test-laravel/public/list_manager」から、一覧画面を表示します。
どのデータでもいいので、「編集」ボタンをクリックします。
「ログインID」のフォームに表示されている文字は、「編集」ボタンを押したログインIDと一致するでしょうか?
エラーが表示されず、「ログインID」のフォームに想定していたデータが表示されればOKです!
ルーティングの設定ファイルを編集する
では編集ボタンが押された時用に、ルーティングの設定ファイルを編集しましょう!
Route::PUT('/edit_manager', 'App\Http\Controllers\ManagerController@update');
再度、コントローラーファイルを編集する
では再びコントローラーファイルを編集します。
手順1:コントローラーファイルを編集する
「ManagerController.php」に以下のソースを追記します。
public function update(Request $request)
{
// バリデーションの記述
$request->validate([
'login_id' => ['required','unique:managers,login_id,' . $request->id . ',id'],
'password' =>['required'],
]);
$manager = Manager::find($request->id);
$manager->update([
"login_id" => $request->login_id,
"password" => $request->password,
]);
$message = "更新が完了しました。";
$Manager_Date = Manager::where('id', $request->id)->first();
return view('edit_manager', compact('message','Manager_Date'));
}
バリデーションは登録時とは若干異なります。
// 登録時のログインIDのバリデーション
'login_id' => ['required','unique:managers'],
// 編集時のログインIDのバリデーション
'login_id' => ['required','unique:managers,login_id,' . $request->id . ',id'],
「unique」のバリデーションチェックを大きく変えました。
「unique」は重複チェックでしたね。
登録の時は全データをチェックすればOKでしたが、更新の時に全データをチェックしてしまうと「自分のデータ」もチェック対象になってしまいます。
例えば、ログインIDを変更しない、かつ、パスワードのみ変更しようとした場合、「すでに登録されているログインIDです」とバリデーションエラーになって登録できなくなってしまいます。
それを回避するのが「’unique:managers,login_id,’ . $request->id . ‘,id’」という書き方です。
「unique:テーブル名,検索するカラム名,除外するID,除外するIDのカラム名」という順番で指定してあげます。
バリデーションで問題がなかったら、いよいよデータの更新です。
データの更新は以下のソースです。
$manager = Manager::find($request->id);
$manager->update([
"login_id" => $request->login_id,
"password" => $request->password,
]);
まず$request->idを使って、更新したい該当データを「find()」で検索をかけます。
次に$managerには更新対象の情報が入っているので、「update」メソッドに更新したいカラム名とデータを渡してあげることで更新を行えます。
最後に、また編集画面に戻るように指定してあげれば、コントローラーファイルの編集は完了です!
手順2:ブラウザで動作確認をする
では、またブラウザから「http://localhost/test-laravel/public/list_manager」にアクセスしてみましょう。
編集したいデータの「編集」ボタンをクリックします。
ログインIDを適当に変更したり、パスワードを入力して……。
「送信」ボタンをクリックします!
「更新が完了しました」のメッセージが表示されましたね。
ではもう一度、一覧画面を表示してみましょう。
該当のデータのログインIDが変わりましたね!
これで、更新処理は完了です!
今回のファイルのまとめ
今回は6つのファイルを使用しました。
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
// 2023.02.18 追記
Route::get('/hello', 'App\Http\Controllers\HelloController@index');
// 2023.03.11 追記
Route::get('/register_manager', 'App\Http\Controllers\ManagerController@index');
Route::post('/register_manager', 'App\Http\Controllers\ManagerController@register');
// 2023.03.25 追記
Route::get('/list_manager', 'App\Http\Controllers\ManagerController@list');
// 2023.04.01 追記
Route::DELETE('/list_manager', 'App\Http\Controllers\ManagerController@delete');
// 2023.04.08 追記
Route::get('/edit_manager/{id}', 'App\Http\Controllers\ManagerController@edit');
Route::PUT('/edit_manager', 'App\Http\Controllers\ManagerController@update');
さいごに
今回は「Laravel」の入門編8として、データベースのテーブルに登録したレコードを更新する方法と、登録と編集のビューファイルを共通化する方法を解説しました。
今回は今までよりずっと多くのファイルを触ってきたので、難しかったかもしれません。
しかし何度も言いますが、更新機能は、ほぼすべてのシステムで存在しているといっても過言ではありません!
実際に触ってみて実装方法を覚えておきましょう!
注意すべき点がわかっていれば簡単に実装を行えるようになります。
ぜひこの記事を参考に、システムを作ってみてくださいね!