Laravelバリデーションの条件分岐をルールやif文で実現

Laravelのバリデーション機能は非常に強力であり、データの整合性を保つための重要な機能です。

本記事では、Laravelのバリデーション機能を使用していくなかで、実務でも使える「バリデーションの条件分岐」を行う方法について詳しく説明します。

以下の内容を取り上げていきます

  • Validator::make() を使用したif文での条件分岐
  • sometimesバリデーションルールを使った条件分岐
  • required_ifバリデーションルールを使った条件分岐

Laravelバリデーションの基本

Laravelでは、コントローラやフォームリクエストクラスを使用してバリデーションルールを定義します。

基本的なバリデーションルールは、requirednumericemailなどのような基本的なバリデーションルールで構成されています。

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

1. Validator::make()を使用したif文での条件分岐

通常であれば $request->validate を使用してバリデーションの実行をしますが、この場合はバリデーションエラーが発生すると入力ページに自動的に遷移されてしまいます。

これを回避するために Validator::make を使用することでバリデーションエラー時の処理を条件分岐させることができます。

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

public function store(Request $request)
{
    $validator = Validator::make($request->all(), [
        'name' => 'required',
    ]);

    if ($validator->fails()) {
        // nameのバリデーションエラーが発生した場合の処理
    }

    $validator = Validator::make($request->all(), [
        'email' => 'required|email',
    ]);

    if ($validator->fails()) {
        // emailのバリデーションエラーが発生した場合の処理
    }

    // バリデーションが成功した場合の処理
}

この方法を使用することで条件分岐させることは可能ですが、処理の記述が長くなるデメリットもあります。

以下で紹介するLaravelに搭載されているバリデーションルールを使用することでより簡潔に処理を書く事ができます。

2. sometimesバリデーションルールの概要

sometimesバリデーションルールは、条件に応じてバリデーションルールを適用するための強力な機能です。

これにより、特定の条件が満たされた場合にのみバリデーションルールを適用することができます。

このパラメータは、入力データの特定のフィールドに関する条件を確認し、その条件に基づいてバリデーションルールを動的に適用するために使用されます。

sometimesバリデーションルールの使用例

以下の例を使用して、sometimesバリデーションルールを使った条件分岐の手法を示します。

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

public function store(Request $request)
{
    $request->validate([
        'name' => 'required',
        'email' => 'sometimes|required|email', // 存在する時だけ必須確認
    ]);

    // バリデーションが成功した場合の処理
}

上記の例では、nameフィールドは常に必須ですが、emailフィールドは条件によって必須であるかどうかが変わります。

具体的には、emailフィールドは存在する場合には必須のバリデーションが実行されます。

3. required_ifバリデーションルールの概要

required_ifバリデーションルールは、特定の条件が満たされた場合にのみ、指定したフィールドを必須とします。

このルールは、2つの引数を受け取ります。最初の引数は条件フィールドであり、2番目の引数は条件の値です。

条件フィールドが指定された値と等しい場合、指定したフィールドが必須となります。

required_ifバリデーションルールの使用例

以下の例を使用して、required_ifバリデーションルールの具体的な使用方法を示します。

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

public function store(Request $request)
{
    $request->validate([
        'name' => 'required',
        'role' => 'required',
        'phone' => 'required_if:role,admin', // roleパラメータがadminの時のみ必須
    ]);

    // バリデーションが成功した場合の処理
}

上記の例では、nameフィールドとroleフィールドは常に必須です。しかし、phoneフィールドは、roleフィールドの値がadminである場合にのみ必須となります。

例えば、roleadminである場合、以下のようなデータが送信されるとバリデーションエラーになります。

{
  "name": "John Doe",
  "role": "admin",
  "phone": null
}

上記のデータでは、phoneフィールドが必須であるにも関わらず、値がnullです。そのため、バリデーションエラーが発生します。

required_ifバリデーションルールによる複雑な条件

required_if ルールに対してより複雑な条件を作成したい場合は、Rule::requiredIf メソッドを使用できます。

このメソッドはBool値、またはクロージャを受け入れます。

クロージャが渡されると true または false を返して、検証中のフィールドが必要かどうかを示す必要があります。

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($request->all(), [
    'role_id' => Rule::requiredIf($request->user()->is_admin),
]);
 
Validator::make($request->all(), [
    'role_id' => Rule::requiredIf(fn () => $request->user()->is_admin),
]);

最後に

Laravelのバリデーション機能を使用することで、柔軟な条件付きのバリデーションルールを簡単に作成できます。

以上の3種類の使い方を使いこなすことでバリデーションの条件分岐に対応する事が可能になります。

この他にもバリデーションを実際に使ってきたノウハウをまとめた記事もあるので、こちらも参考にしてみてください。