バリデーション(validation)とは

入力フォームで入力した値をチェックすることをバリデーションと呼びます。例えば、ECから商品を購入した場合、必ず住所の入力が必要となります。この時に入力する郵便番号に漏れがないか数字であるかまた郵便番号の桁数が7桁になっているかをチェックすることがバリデーションです。

動作確認環境の準備

バリデーションの基本設定、バリデーションによるエラーメッセージの表示場所を確認するため、動作確認環境の構築を行います。

動作検証のデータベースの場合はsqliteデータベース環境を構築すると簡単です。

postsテーブルの準備

動作確認を行うためにpostsテーブルを作成します。postsテーブルは、titleとbodyの2つ列から構成されます。

Postモデルとマイグレーションファイルの作成を行います。Postモデルと同時にマイグレーションファイルも作成するためphp artisan make:modelコマンドに-mオプションをつけて実行します。


mac$ php artisan make:model Post -m
Model created successfully.
Created Migration: 2019_01_01_053048_create_posts_table

モデルPost.phpファイルはappディレクトリの下にマイグレーションファイルはdatabase/migrationsディレクトリの下に作成されます。

postsテーブルを作成するマイグレーションファイルにtitle, bodyの列情報を追加します。


<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

postsテーブルのtitle, body列の挿入が行えるようにPost.phpファイルを更新します。


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'title', 'body', 
    ];    
}

postsテーブルの準備ができたので、php artisan migrateコマンドでpostsテーブルを作成します。


mac$ php artisan migrate
Migrating: 2019_01_01_053048_create_posts_table
Migrated:  2019_01_01_053048_create_posts_table

ルーティングの設定

web.phpに以下のルーティングの設定を行います。


Route::get('post/create', 'PostController@create');

Route::post('post', 'PostController@store');

コントローラーの作成

php artisan make:controllerコマンドを使ってPostController.phpの作成を行います。


mac$ php artisan make:controller PostController
Controller created successfully.

ルーティングファイルweb.phpで追加したcreateメソッドとstoreメソッドを記述します。storeメソッドの中にValidationのロジックを記述します。


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    public function create()
    {
        return view('post.create');
    }

    public function store(Request $request)
    {
        // ここにValidationを行うロジックを記述する
    }
}

ビューの作成

入力フォームを表示させるためのビューの作成を行います。views/postディレクトリの下にcreate.blade.phpを行います。

create.blade.phpファイルの保存場所

create.blade.phpファイルの保存場所

ビューファイルの中身は下記の通りです。


<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Create Post</title>
</head>
<body>
	<form method="POST" action="/post" enctype="multipart/form-data">

		{{ csrf_field() }}

	<p>name:<br>
		<input type="text" name="title" value="">
	</p>

	<p>body:<br>
		<textarea name="body" cols="25" rows="5"></textarea>
	</p>

	<button type="submit">登録する</button>
	</form>
</body>
</html>

/post/createにアクセスすると作成した入力フォームが表示されます。

入力フォーム

入力フォーム

バリデーションのメソッドとルールについて

validateメソッドについて

入力フォームから入力した値のチェックを行うためにPostControllerのstoreメソッド内にバリデーションを追加します。バリデーションはvalidateメソッドを用いて行い、テーブルの各列に対してルールを設定し、入力値のチェックを行います。ルールは各列に対して、複数設定することもできます。複数のルールを設定する場合は、区切り文字”|”を使って分けます。

validateメソッドの記述方法は下記となります。

validateメソッド

validateメソッド

validationの方法には、validateメソッド以外にもValiidationファザードを用いたものなどあります。本文書では一番シンプルなvalidateメソッドを利用することでバリデーションの理解を深めます。

postsテーブルのtitle列には、入力が必須となるルールrequiredと入力した行と重複の確認を行うルールuniqueが設定されています。body列には、ルールrequiredのみ設定しています。


public function store(Request $request)
{
    $request->validate([
	     'title' => 'required|unique:posts',
	     'body' => 'required',
    ]);
}

validateメソッドを使用して、バリデーションに失敗した場合、自動で入力フォーム画面に移動します。

バリデーションルール

required, unique以外にもたくさんのバリデーションルールがあります。Laravelのドキュメントを確認しながら、必要なルールを見つけ、適用していきます。

バリデーションルール一覧

バリデーションルール一覧

ビューへのエラーメッセージ要素の追加

validationに失敗した場合のエラーメッセージを表示できるように入力フォームのビューであるcreate.blade.phpにメッセージを表示できる要素を追加します。


	@if ($errors->any())
	    <div class="alert alert-danger">
	        <ul>
	            @foreach ($errors->all() as $error)
	                <li>{{ $error }}</li>
	            @endforeach
	        </ul>
	    </div>
	@endif

変数$errorsは、バリデーションを実行するしないに関わらずビューの中で利用することが可能な変数です。

$errors->any()は、変数$errorsの中にエラーメッセージがあるかどうかチェックを行うメソッドです。エラーメッセージがあればtrue、なければfalseを戻します。

$errors->all() は、バリデーションの中のチェックで発生したエラー情報が配列として保持されています。foreachを使用することで1つ1つのメッセージを取り出すことができます。

エラーメッセージの表示

バリデーションの動作確認を行うため入力フォームには、何も入力せず登録ボタンをクリックします。

入力フォーム

入力フォーム

titleにもbodyにも入力を行なっていなかったため、field is requiredのメッセージが表示されます。

エラーメッセージの表示

エラーメッセージの表示

カスタマイズしたエラーメッセージの設定

初期設定では、エラーメッセージは英語で表示されています。メッセージをカスタマイズすることも可能です。以下のようにvalidateメソッドに表示したいメッセージの配列を追加します。


public function store(Request $request)
{
    $request->validate([
	     'title' => 'required|unique:posts',
	     'body' => 'required',
    ],
      [
             'title.required' => 'タイトルは必須です。',
             'body.required'  => 'bodyは必須項目です。',
      ]);
}

再度入力フォームに何も入力せず、登録ボタンを押すと追加したカスタマイズしたメッセージが表示されます。

カスタマイズしたエラーメッセージ

カスタマイズしたエラーメッセージ

エラーメッセージの日本語化

エラーメッセージをカスタマイズして日本語化する方法の確認を行いましたが、validation毎に個別に設定を行うのは非効率のため、一括で日本語化を行う方法を確認します。日本語化までの流れは下記の通りです。

  1. config/app.phpファイルでロケールの変更
  2. resources/langディレクトリにjaディレクトリ作成
  3. resources/lang/en/validation.phpファイルをjaディレクトリに複製
  4. validation.phpファイルの更新

validationのエラーメッセージの一覧が登録されているファイルは、resources/lang/en/validation.phpに登録されています。


<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages here.
    |
    */

    'accepted' => 'The :attribute must be accepted.',
    'active_url' => 'The :attribute is not a valid URL.',
        ・
    'required' => 'The :attribute field is required.',
        ・

ロケールの設定

初期設定では、ロケールの設定が”en”になっているために”ja”に変更する必要があります。設定ファイルは、Laravelインストールディレクトリのconfig/app.phpで行います。下記のように’en’を’ja’に変更します。


    /*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */

    'locale' => 'ja',

validation.phpファイルの複製

app.phpファイルでロケールの作成完了後、resources/langディレクトリにjaディレクトリを作成し、enディレクトリに保存されているvalidation.phpファイルをjaディレクトリの下に保存します。保存したvalidation.phpの中にあるrequiredを日本語に変更します。

validationメッセージを日本語化

validationメッセージを日本語化

再度入力フォームに何も入力せず、ja/validation.phpファイルで日本語化したメッセージが表示されます。

validation.phpで日本語化したエラーメッセージ

validation.phpで日本語化したエラーメッセージ

requiredのみ日本語化を行いましたが、他のメッセージも日本語に変更すれば、すべてのエラーメッセージを日本語化することが可能です。

エラーメッセージの表示場所

エラーメッセージに取得に関するメソッド

入力した値毎にエラーメッセージを表示することが可能です。下記の方法で入力した項目のエラーメッセージを取り出すことが可能です。

firstメソッドでエラーメッセージを取得

firstメソッドでエラーメッセージを取得

firstメソッドでは、項目のvalidationでエラーになったルールの1つしか取得することができません。すべてのルールのエラーメッセージを取得するためには、getメソッドを使用します。

getメソッドですべてのエラーを取得

getメソッドですべてのエラーを取得

getメソッドの場合、エラーメッセージは配列で取得されるため、foreachでテキストとして取得する必要があります。

各項目にエラーメッセージが入っているかどうかをチェックするhasメソッドもあります。

エラーメッセージを持っているかの確認

エラーメッセージを持っているかの確認

項目ごとのエラーメッセージ

hasメソッドとfirstメソッドを利用してエラーメッセージを表示します。


@if($errors->has('body'))
  {{ $errors->first('body') }}
@endif

hasメソッドとgetメソッドを利用してエラーメッセージを表示します。


@if($errors->has('title'))
   @foreach($errors->get('title') as $message)
      {{ $message }}
@endforeach @endif

項目別にエラーメッセージを表示

これまでのエラーメッセージの設定を使って、エラーメッセージを表示場所を項目の下に表示させます。


<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Create Post</title>
</head>
<body>

	<form method="POST" action="/post" enctype="multipart/form-data">

		{{ csrf_field() }}

	<p>title:<br>
		@if($errors->has('title'))
			@foreach($errors->get('title') as $message)
				{{ $message }}<br>
			@endforeach
		@endif 
		<input type="text" name="title" value="">
	</p>

	<p>body:<br>
		@if($errors->has('body'))
			{{ $errors->first('body') }}<br>
		@endif 
		<textarea name="body" cols="25" rows="5"></textarea>
	</p>

	<button type="submit">登録する</button>

	</form>

</body>
</html>

再度入力フォームに何も入力せず、登録ボタンを押すと入力項目の下にエラーメッセージが表示されます。

エラーメッセージの表示場所を変更

エラーメッセージの表示場所を変更

入力項目毎にエラーメッセージを表示することでどの入力が間違っているかすぐにわかるためユーザビリティも向上します。