目標
Laravelのバリデーションの基礎を知って、ある程度は使えるようにする
バリデーションって?
フォームなどの入力内容に対してエラーなどを表示する機能。
入力必須のフォームなのに、何も入力されてなかったらエラーメッセージなどを表示できるようになる。
こんな感じに(↓)
バリデーション作成
リクエストの作成
そもそもバリデーション
とは機能。
その機能を使えるようにするファイルはrequest
で作成する。
ターミナルで下記を実行して、バリデーションを使えるようにするリクエストファイルを作成する。
$ php artisan make:request ValidationRequest(作成したいファイル名)
このコマンドを実行すると、(プロジェクト名)\app\Http\Requests
にターミナルで入力したファイル名のリクエストファイルが作成される。
リクエストファイルを解説
作成したリクエストファイルはこのようなコードが書かれている。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ValidationRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
コメントアウトされている部分に説明があるように、実際のバリデーションのルールなどを記載していくのは、**public function rules()
**の中。
**public function authorize()
**は認証機能などを有効化している際、現在ページを操作しているユーザーが認証されたユーザーかどうかを判定するというもの。
デフォルトでtrue
、有効化されているが、必要なければfalse
にしておく。
バリデーションルールを作成する
今回は冒頭にあったユーザー検索画面のバリデーションルールを作成してみる。
バリデーションで確認される入力内容を設定するファイルはこんな感じ。
本当のファイル名はsearch.blade.php
だが、見栄えのために.php
ファイルとして見せる。
<div class="card-header">
ユーザー検索
</div>
<div class="card-body">
<p>検索したいユーザーの情報を入力してください。</p>
<div class="search">
<form method="post" action="result">
<div class="category">
<p>検索項目: </p>
<select name="search_category">
<option value="0" selected>選択してください</option>
@for($i = 0; $i < 4; $i++)
<option value="{{ $NAME[$i] }}">{{ $NAME[$i] }}</option>
@endfor
</select>
</div>
<div class="word">
<p>検索ワード: </p>
<input type="text" name="search_word">
</div>
<input type="submit" value="検索する">
@csrf
</form>
</div>
そこまで重要じゃないので、serch_category
というセレクターとsearch_word
という入力フォームがあり、result
にそれらの値が送られることを把握してもらえれば十分。
それらのフォームにおけるバリデーションとして、以下のようなルールを作成した。
public function authorize()
{
return true;
}
public function rules()
{
return [
'search_category' => 'not_in:0',
'search_word' => 'required',
];
}
バリデーションルールは**'バリデーション対象となるフォームのname' => 'バリデーションルール'
** という形で指定していく。
今回設けたルールを説明していく。
search_category
のnot_in:0
はvalue='0'以外の値を選択してください
というルール。
search_word
のrequired
は入力必須
のルール。
他にも多様なルールがあるが、必要に応じて公式ドキュメントなどを調べるのがオススメ。
バリデーションルールを適用する
では、作ったルールを適用していく。
バリデーションルールを記載したリクエストファイルの適用先はコントローラーとなる。
そして、その適用されるコントローラーは値を入力するページのコントローラーではなく、入力された値を受け取ったり、送られたりするページのコントローラーである。
そのため、今回の例でいえば、フォームの送信先、result
のコントローラーにバリデーションルールを適用していく。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\SearchRequest;
use App\User;
class ResultController extends Controller
{
public function result(SearchRequest $request)
{
$category = $request -> input('search_category');
$word = $request -> input('search_word');
$search_data = array(
'category' => $category,
'word' => $word
);
$user_data = User::where($category, 'like', "%$word%") -> get();
return view('user/result',['Search' => $search_data, 'User' => $user_data]);
}
}
適用するといっても、use App\Http\Requests\SearchRequest;
で作成したリクエストを宣言して、result()
の中に(SearchRequest $request)
を記入するだけ。
こうすることで、result()
の処理が実行される前に送信された値に対してSearchRequest
が働き、ルールを満たしていなかったらその後の処理を行わず、その前の画面、入力画面へと戻される。
入力画面に戻される際、GET
メソッドでリダイレクトされるため、ルーティング処理などに注意が必要。
バリデーションルールを適用するコントローラはデータを送られる側のコントローラー である事を覚えておきたい。
バリデーションエラーを表示する
このままページを動かしても、何も表示されず画面が変わらないだけなので、バリデーションルールを満たしていないことを伝える必要がある。
そのためにも、~.blade.php
ファイルを次のように変更する。
//中略
<div class="word">
<p>検索ワード: </p>
<input type="text" name="search_word">
</div>
<input type="submit" value="検索する">
@csrf
</form>
@if(count($errors) > 0)
<ul class="error">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
</div>
バリデーションルールを満たしていない場合、$errors
にエラーメッセージが格納される。
この状態でバリデーションルールを満たしていない場合、次のようにエラーが表示される。
cssでエラーメッセージを赤くするように変更してあるが、これでバリデーション機能は実装することができた。
.error{
color: red;
font-size: 15px;
}
バリデーションのカスタマイズ
エラーメッセージをカスタマイズする
バリデーションルールを満たしていない場合、エラーメッセージを表示できるようになったが、エラーメッセージが英語である。
日本語にしたいだけでなく、自分好みにカスタマイズしたい場合もあるだろう。
そのような場合は、次のようなコードを入力する。
//中略
public function rules()
{
return [
'search_category' => 'not_in:0',
'search_word' => 'required',
];
}
public function messages() {
return [
'search_category.not_in' => '検索カテゴリーを入力してください。',
'search_word.required' => '検索ワードは20字以内で入力してください。',
];
}
エラーメッセージは**messages()
でカスタマイズできる。
その内容は、バリデーション対象のname.バリデーションルール => 表示したいメッセージ
**で宣言する。
今回はバリデーション対象の両方においてルールが1つずつしかないためこのような形になったが、複数のルールがある場合は以下のように宣言できる。
public function rules()
{
return [
'entry_name' => 'required|max:20|unique:user,name',
];
}
public function messages() {
return [
'entry_name.required' => '名前を入力してください。',
'entry_name.max' => '名前は20字以内で入力してください。',
'entry_name.unique' => 'この名前は既に利用されています。',
];
}
エラーメッセージ表示場所のカスタマイズ
先程の写真ではエラーメッセージが一ヶ所にまとまっていたが、冒頭ではそれぞれの項目ごとにそれぞれのエラーメッセージが表示されていた。
そのような表示にしたいときは、次のようにコードを入力する。
//中略
<form method="post" action="result">
<div class="category">
<p>検索項目: </p>
<select name="search_category">
<option value="0" selected>選択してください</option>
@for($i = 0; $i < 4; $i++)
<option value="{{ $NAME[$i] }}">{{ $NAME[$i] }}</option>
@endfor
</select>
</div>
@if($errors->has('search_category'))
<div class="error">
<p>{{ $errors->first('search_category') }}</p>
</div>
@endif
<div class="word">
<p>検索ワード: </p>
<input type="text" name="search_word">
</div>
@if($errors->has('search_word'))
<div class="error">
<p>{{ $errors->first('search_word') }}</p>
</div>
@endif
<input type="submit" value="検索する">
@csrf
</form>
エラーメッセージを表示するコードについて説明していく。
**@if($errors->has('バリデーション対象のname'))
で、バリデーション対象のname
に対してエラーメッセージが$errors
に格納されているかを判断する。
格納されているようであれば、{{ $errors->first('バリデーション対象のname') }}
**で、対象における最初のエラーメッセージを表示するよう指定している。
ここまでのコードをファイルに反映させれば、冒頭の画像のようなバリデーション機能を利用できるようになる。
バリデーションを更に使いこなす
入力値の保持
バリデーションルールを満たさない値が入力されても、その値をフォームなどに保持したい。
そのような際は、表示用のページのフォームなどに次のようなvalue
の設定をする。
<input type="text" name="name" value="{{ old('name') }}">
**{{ old('バリデーション対象のname') }}
**を設定することで、バリデーションルールに満たさなくても値が保持される。
また、old
関数では初期値を第二引数で指定できる。
その場合は、**{{ old('バリデーション対象のname', '0') }}
**といった形になる。