2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravelのバリデーションにおける基礎をまとめる

Last updated at Posted at 2020-09-04

目標

Laravelのバリデーションの基礎を知って、ある程度は使えるようにする

バリデーションって?

フォームなどの入力内容に対してエラーなどを表示する機能。
入力必須のフォームなのに、何も入力されてなかったらエラーメッセージなどを表示できるようになる。
こんな感じに(↓)

image.png

バリデーション作成

リクエストの作成

そもそもバリデーションとは機能。
その機能を使えるようにするファイルはrequestで作成する。

ターミナルで下記を実行して、バリデーションを使えるようにするリクエストファイルを作成する。

 $ php artisan make:request ValidationRequest(作成したいファイル名)

このコマンドを実行すると、(プロジェクト名)\app\Http\Requestsにターミナルで入力したファイル名のリクエストファイルが作成される。

リクエストファイルを解説

作成したリクエストファイルはこのようなコードが書かれている。

(プロジェクト名)\app\Http\Requests\ValidationRequest.php
<?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ファイルとして見せる。

search(.blade).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にそれらの値が送られることを把握してもらえれば十分。

それらのフォームにおけるバリデーションとして、以下のようなルールを作成した。

ValidationRequest.php
public function authorize()
{
    return true;
}

public function rules()
{
    return [
        'search_category' => 'not_in:0',
        'search_word' => 'required',
    ];
}

バリデーションルールは**'バリデーション対象となるフォームのname' => 'バリデーションルール'** という形で指定していく。
今回設けたルールを説明していく。

search_categorynot_in:0value='0'以外の値を選択してくださいというルール。
search_wordrequired入力必須のルール。

他にも多様なルールがあるが、必要に応じて公式ドキュメントなどを調べるのがオススメ。

バリデーションルールを適用する

では、作ったルールを適用していく。
バリデーションルールを記載したリクエストファイルの適用先はコントローラーとなる。
そして、その適用されるコントローラーは値を入力するページのコントローラーではなく、入力された値を受け取ったり、送られたりするページのコントローラーである。
そのため、今回の例でいえば、フォームの送信先、resultのコントローラーにバリデーションルールを適用していく。

(プロジェクト名)\app\Http\Controllers\ResultController.php
<?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ファイルを次のように変更する。

search(.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にエラーメッセージが格納される。
この状態でバリデーションルールを満たしていない場合、次のようにエラーが表示される。
image.png

cssでエラーメッセージを赤くするように変更してあるが、これでバリデーション機能は実装することができた。

style.css
.error{
  color: red;
  font-size: 15px;
}

バリデーションのカスタマイズ

エラーメッセージをカスタマイズする

バリデーションルールを満たしていない場合、エラーメッセージを表示できるようになったが、エラーメッセージが英語である。
日本語にしたいだけでなく、自分好みにカスタマイズしたい場合もあるだろう。
そのような場合は、次のようなコードを入力する。

ValidationRequest.php

//中略

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つずつしかないためこのような形になったが、複数のルールがある場合は以下のように宣言できる。

SampleRequest.php
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' => 'この名前は既に利用されています。',
    ];
}

エラーメッセージ表示場所のカスタマイズ

先程の写真ではエラーメッセージが一ヶ所にまとまっていたが、冒頭ではそれぞれの項目ごとにそれぞれのエラーメッセージが表示されていた。
そのような表示にしたいときは、次のようにコードを入力する。

search(.blade).php

//中略

<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の設定をする。

sample(.blade).php
<input type="text" name="name" value="{{ old('name') }}">

**{{ old('バリデーション対象のname') }}**を設定することで、バリデーションルールに満たさなくても値が保持される。

また、old関数では初期値を第二引数で指定できる。
その場合は、**{{ old('バリデーション対象のname', '0') }}**といった形になる。

バリデーションをより使いこなす

参考文献

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?