今回は入力フォームで入力した内容にエラーがないかチェックする方法を解説します。
Laravelだと「バリデーション」と呼びます。
たとえば前回、管理者情報テーブルにIDとパスワードを登録する画面を作りました。
この入力フォームで1件データを登録後、1件目と同じ「ログインID」を登録しようとすると以下のようなエラー画面が表示されてしまいます。
このエラーが出てしまう原因は、テーブル構成を「ログインIDはユニーク制約」で作成したからです。
ユニーク制約をつけたカラムは、同じ値のデータを格納できなくなります。
また、ログインIDやパスワードを未入力のまま登録されてしまうのは避けたいものです。
このように、意図せずエラー画面が出ないようにしたり、意図しない値がテーブルに登録されないようにしたりするために、バリデーションの設定は不可避です。
今回はそんなバリデーションの基本の設定方法を解説していきます。
前回のファイル一覧
前回作成した以下のファイルを基に、解説していきます。
<?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');
// 今回はここから下2行を追記!!
Route::get('/register_manager', 'App\Http\Controllers\ManagerController@index');
Route::post('/register_manager', 'App\Http\Controllers\ManagerController@register');
バリデーションの作成
ではバリデーションの作成手順を解説していきます!
手順1:コントローラのファイルにバリデーションの処理を追加
前回は「ログインID」と「パスワード」の入力フォームがありました。
今回は以下のようなエラーチェックを行います。
ログインID:必須、指定されたテーブルに入力値が存在しないか
パスワード:必須
バリデーションのコードで書くと以下のようになります。
送信ボタンを押された時の処理の一番上に、以下のコードを追加しましょう!
$request->validate([
'login_id' => ['required','unique:managers'],
'password' =>['required'],
]);
各項目名の後ろに注目してみてください。
「required」と「unique」を書いてますが、それぞれの意味は以下のとおりです。
required:入力値が空やNULLはNG
unique:指定されたテーブルに入力値と同じ値が存在するとNG
「unique」で指定するテーブル名は「:」で区切って、後ろに書きます。
さて、これで実際に動作確認をしてみます。
「ログインID」や「パスワード」を未入力、またはすでに登録されている「ログインID」を入力して「送信」ボタンを押すと、エラー画面ではなく、元の画面に戻りますね。
データベースも確認しても、データが登録されていません。
バリデーションに引っかかると、そこで処理がストップして元の画面に戻るからです。
しかし、これでは「登録できない理由」が操作している人に伝わりません。
そこでエラーメッセージを表示する必要があります。
次にエラーメッセージを表示する方法をお伝えします。
手順2:ビューでエラーメッセージを表示させる
ビューのエラーメッセージを表示したい場所にコードを追加します。
エラーメッセージをまとめて表示したい場合と、各入力フォームごとに表示したい場合がありますので、それぞれ解説します。
エラーメッセージをまとめて表示したい場合
ビューファイル「register_manager.blade.php」で、エラーメッセージを表示したい場所に以下のソースを記述します。
@if ($errors->any())
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
「@if ($errors->any())」でエラーメッセージがあるか確認。
「$errors->all()」にエラーメッセージが配列で保存されているので、ループしながら表示させています。
この書き方だと、以下のような表示になります。
今はエラーメッセージが英語表記になっていますが、この記事の後半で日本語に変更していきます!
エラーメッセージを各入力フォームごとに表示したい場合
エラーメッセージは項目ごとに取り出すことも可能です。
{{ $errors->first('項目名') }} // 1つのメッセージのみ取り出す
複数のメッセージを取得する場合は「get()」を使用します。
取り出し方は以下のとおりです。
@foreach($errors->get('項目名') as $message)
{{ $message }}<br>
@endforeach
各項目にエラーメッセージが入っているかどうかをチェックするのは、「has()」を使用します。
$errors->has('項目名')
実際にどう使っていくのか実際に書いてみましょう!
まずはエラーがあることを知らせするソースを記述します。
@if ($errors->any())
エラーがあるので確認してください。
@endif
そして、各入力フォームの下にエラーメッセージを表示するソースを記述していきます!
ログインID:<br>
<input type="text" name="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
「ログインID」と「パスワード」のエラーチェックは以下の内容でしたね。
ログインID:必須、指定されたテーブルに入力値が存在しないか
パスワード:必須
「ログインID」は複数のチェックがあったので「get()」を使用しています。
一方の「パスワード」は1つのチェックだったので「first()」で十分です。
この書き方だと以下のような表示になります。
こちらの方が、どこの入力フォームに誤りがあるのか視覚的に分かりやすいので、よく利用されています。
入力フォームごとにエラーメッセージが出力される書き方を覚えておくのがおすすめです!
また、バリデーションで画面に戻ってしまった時、入力値を保持しておきたい項目がありますよね。
その場合は以下の記述を行います。
{{ old('項目名') }}
今回の場合、「ログインID」を保持しておきたいので、「input」タグを以下のように書き換えます。
<input type="text" name="login_id" value="{{ old('login_id') }}"><br>
これで以下の画面のように、エラーがあって画面に戻ってきたときも、入力値を保持したままにできます。
次に、今のままだとエラーメッセージや、項目名が英文になっているので直していきます。
手順3:エラーメッセージを日本語にする
まずはエラーメッセージの英文を日本語に直していきます。
まずは「config/app.php」ファイルを開いてください。
スクロールすると、以下のソースが見つかります。
'locale' => 'en',
初期値は英語の「en」になっていますね。
参照先を「日本語で作るエラーメッセージをまとめたファイル」に変更したいので、「ja」に変更してください。
'locale' => 'ja',
次に「lang/en」フォルダに「validation.php」があることを確認してください。
「validation.php」のファイル名の上で左クリックをして開いたメニューから「コピー」を選択します。
次に、「lang」のフォルダ名の上で左クリックをして開いたメニューから「新しいフォルダ…」を選択します。
フォルダ名は「ja」にしてください。
「ja」フォルダは作成できたでしょうか?
では次に、「ja」フォルダの上で左クリックをして、開いたメニューから「貼り付け」を選択します。
「ja」フォルダの中に「validation.php」の複製ができました!
このファイルを開くと、ずらずらと英語でエラーメッセージが書かれていますね。
これをすべて日本語化するのは途方もないので、今使ったエラーメッセージのみ日本語化します。
最初に「必須チェック:required」のエラーメッセージを変更します。
「required」でファイル内検索をするとすぐに見つけることができます。
'required' => 'The :attribute field is required.',
上記の部分を以下に変更します。
「:attribute」は入力フォームの項目名が入るので、うまく利用しましょう!
'required' => ':attribute は必須です。',
続いて「テーブルの存在チェック:unique」のエラーメッセージを修正します。
該当箇所は以下のソースです。
'unique' => 'The :attribute has already been taken.',
ここを下記に書き換えます。
'unique' => ':attribute は既に使用されています。',
これでブラウザでエラーを表示させてみましょう!
エラーメッセージが日本語化しましたね!
でもまだ項目名が英語のままなので、項目名も日本語に変更していきます。
手順4:エラーメッセージの項目名を日本語にする
エラーメッセージに表示されている項目名は、入力フォームタグの「name」で指定した名前です。
例えば今回のビューファイルを見ると、「ログインID」の入力フォームタグは以下のソースです。
このソースの「name=”login_id”」が項目名にあたります。
<input type="text" name="login_id" value="{{ old('login_id') }}">
「name」を日本語にすれば解決できるのですが、それだとスマートではなくなり、追々不都合が出てくるので別の方法で変更していきます。
先ほど編集していた「validator.php」ファイルの一番下までスクロールしてください。
「attributes」の記述があります。
'attributes' => [],
「attributes」に使用する項目名を追加すると、しっかり日本語名に変換してくれます。
たとえば今回の「ログインID」と「パスワード」の項目名を変更する場合、以下のソースを記述します。
'attributes' => [
'login_id' => 'ログインID',
'password' => 'パスワード'
],
ブラウザで動作確認を行うと、エラーメッセージが以下のように変わったのを確認できます。
エラーメッセージを完全に日本語化できましたね!
今回のファイルのまとめ
今回は4つのファイルを使用しました。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Manager;
class ManagerController extends Controller
{
public function index()
{
return view('register_manager');
}
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 = "登録が完了しました。";
return view('register_manager', compact('message'));
}
}
さいごに
今回はLaravelの入門編5として、バリデーションの書き方を紹介しました。
エラーチェックは必ず必要になってくるので、覚えておきましょう!
バリデーションの内容は今回紹介した「必須チェック」と「テーブルの存在チェック」以外にも数多くあります。
覚えきれる量ではないので、必要になった時に都度調べるのがおすすめです。
ぜひ次の入門編の記事も参考にしてみてくださいね!