LoginSignup
6
7

More than 3 years have passed since last update.

Laravelにおける複数フィールドの最低限必須のバリデーション

Posted at

TL;DR

required_without_allルールを使いましょう。

required_without_allルールについてと挙動の確認

スクリーンショット 2019-11-27 11.43.08.png

公式ドキュメントを丹念に探せば見つかるのですが、わかりづらいバリデーションとして、
複数あるフィールドの中で、最低限ひとつは入力してもらいたい場合をチェックするバリデーションがあると思います。
例えば上のキャプチャのような、いくつかのSNSアカウントを入力するフィールドがあって、その中のどれかひとつでも入力してくれればオーケーみたいな場合です。
これはrequired_without_allルールでバリデーションできます。

https://laravel.com/docs/6.x/validation#rule-required-without-all
https://readouble.com/laravel/6.x/ja/validation.html#rule-required-without-all

指定した他のフィールドがすべて存在していない場合、このフィールドが存在し、かつ空でないことをバリデートします。

よく読めばこれが求めていたルールです! と納得するのですが、流し見程度だとちょっとわかりづらい。。
そこで今回はフォームリクエストのサンプルを作り、それをテストしてrequired_without_allルールの動きを確認します。
尚、Laravelのバージョンは6です。

$ php artisan make:request SampleFormRequest
Request created successfully.
$ php artisan make:test --unit SampleFormRequestTest
Test created successfully.
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SampleFormRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'qiita'     => 'required_without_all:github,twitter,instagram',
            'github'    => '',
            'twitter'   => '',
            'instagram' => '',
        ];
    }

    public function messages()
    {
        return [
            'qiita.required_without_all' => 'Qiita / GitHub / Twitter / Instagramの中で1個以上の項目を必ず入力してください。',
        ];
    }
}

required_without_allのパラメータで他の項目を羅列します。

<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Support\Facades\Validator;
use App\Http\Requests\SampleFormRequest;

class SampleFormRequestTest extends TestCase
{
    /**
     * required_without_allルールのフォームリクエストのテスト
     *
     * @dataProvider validationDataProvider
     *
     * @param array $inputs
     * @param array $expected
     * @return void
     */
    public function testValidation(array $inputs, array $expected)
    {
        $request   = new SampleFormRequest();
        $validator = Validator::make($inputs, $request->rules(), $request->messages());
        $result    = $validator->passes();
        $errors    = $validator->errors();

        $this->assertEquals($expected['response'], $result);
        $this->assertEquals($expected['errors'], $errors->toArray());
    }

    public function validationDataProvider()
    {
        return [
            'エラー' => [
                [
                    'qiita'     => '',
                    'github'    => '',
                    'twitter'   => '',
                    'instagram' => '',
                ],
                [
                    'response' => false,
                    'errors'   => [
                        'qiita' => ['Qiita / GitHub / Twitter / Instagramの中で1個以上の項目を必ず入力してください。'],
                    ]
                ]
            ],
            '正常1' => [
                [
                    'qiita'     => 'kiyc',
                    'github'    => '',
                    'twitter'   => '',
                    'instagram' => '',
                ],
                [
                    'response' => true,
                    'errors'   => []
                ]
            ],
            '正常2' => [
                [
                    'qiita'     => '',
                    'github'    => 'kiyc',
                    'twitter'   => '',
                    'instagram' => '',
                ],
                [
                    'response' => true,
                    'errors'   => []
                ]
            ],
        ];
    }
}
$ vendor/bin/phpunit tests/Unit/SampleFormRequestTest.php 
PHPUnit 8.4.1 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 396 ms, Memory: 16.00 MB

OK (3 tests, 6 assertions)

すべて未入力だとエラーになり、ルールを指定したフィールドに入力がある場合、またはルールを指定していないフィールドに入力がない場合でもエラーにならないことを確認できました:beer:
このルールを見つけられなかったばかりに、私はわざわざカスタムルールを作ってしまったので、皆さん公式ドキュメントはしっかり読みましょう:scroll:

6
7
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
6
7