8
5

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 1 year has passed since last update.

[Laravel6] 条件によってバリデーションの内容を変える方法

Last updated at Posted at 2021-01-27

バージョン情報

  • PHP 7.4.2
  • Laravel 6.2

実現したいこと

こんな感じのラジオボタンとテキストの入力フォームがあり、
スクリーンショット 2021-01-28 2.00.41.png

index.html
<input type="radio" name="type" value="A"><label>A</label>
<input type="radio" name="type" value="B"><label>B</label>
<br>
<input type="text" name="text">
  • Aが選択されている時は、textが整数であること
  • Bが選択されている時は、textが文字列であること
  • type, textは必ず入力されていること

こんなバリデーションをしたい。

結論

PostTextRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;

class PostTextRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'type' => 'required',
            'text' => 'required'
        ];
    }
    public function withValidator(Validator $validator)
    {
        $validator->sometimes('text', 'required | integer', function ($input) {
            return $input->type === 'A';
        });

        $validator->sometimes('text', 'required | string', function ($input) {
            return $input->type === 'B';
        });
    }
}

重要なところ

public function withValidator(Validator $validator)
    {
        $validator->sometimes('text', 'required | integer', function ($input) {
            return $input->type === 'A';
        });

        $validator->sometimes('text', 'required | string', function ($input) {
            return $input->type === 'B';
        });
    }

解説

元のコード

元々はこんな感じの記述でした。

TextController.php

public function post(Request $request)
{
    // バリデーションルールの配列を呼び出す
    $validation_rules = $this->rules();

    // typeがAかBかによってバリデーションを追加する
    if ($request->input('type') === 'A') {
        $validation_rules['text'] .= '|integer'; 
    } elseif ($request->input('type') === 'B') {
        $validation_rules['text'] .= '|string';
    }
    // バリデーション実行
    $request->validate($validation_rules);

    // postの処理...
}

protected function rules() 
{
    return [
        'text' => 'requied',
        'type' => 'requied'
    ];
}

これでも期待通りの動きはしてくれるけど、Controllerに全部書いちゃってるし、if文でバリデーションを追加するとかなんかダサい。

withValidator()というのを使うといい感じにできるらしい。

ドキュメント
参考にした記事

書き方としては、

public function withValidator(Validator $validator)
    {
        $validator->sometimes('バリデーションを行うフィールド', 'バリデーション | バリデーション', function ($input) {
            return バリデーションをする条件;
        });
    }

なので、今回のパターンに当てはめると、

PostTextRequest.php
public function withValidator(Validator $validator)
    {
        // textが整数かどうかのバリデーションを追加したい
        $validator->sometimes('text', 'required | integer', function ($input) {
            // typeがAだった時に
            return $input->type === 'A';
        });
        // textが文字列かどうかのバリデーションを追加したい
        $validator->sometimes('text', 'required | string', function ($input) {
            // typeがBだった時に
            return $input->type === 'B';
        });
    }
TextController.php
public function post(PostTextRequest $request)
{
    // postの処理...
}

これでControllerはスッキリするし、スマートに書ける(気がする)。

ご指摘、アドバイスお待ちしております。

8
5
1

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
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?