laravel5.6

Laravel5.6: バリデーション(users)

親記事

Laravel 5.6で基本的なCRUDを作る - Qiita

User用のフォームリクエストを作る

前回の記事とほぼ同じです。

PowerShell
# Post用のフォームリクエストを生成
> php artisan make:request StoreUser
app/Http/Requests/StoreUser.php
    public function authorize()
    {
        // 認可は別の箇所で行うので、ここでは素通りさせる
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required|string|max:191',
            'email' => 'required|string|email|max:191|unique:users',
            'password' => 'required|string|min:6|max:191|confirmed',
        ];
    }
app/Http/Controllers/UserController.php
 // 忘れずにインポートすること!!!!
+use App\Http\Requests\StoreUser;

 class UserController extends Controller
 {
     /**
      * Store a newly created resource in storage.
      *
-     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\Http\Requests\StoreUser $request
      * @return \Illuminate\Http\Response
      */
-    public function store(Request $request)
+    public function store(StoreUser $request)
     {

(中略)

     /**
      * Update the specified resource in storage.
      *
      * @param  \Illuminate\Http\Request  $request
      * @param  \App\User $user
      * @return \Illuminate\Http\Response
      */
     public function update(Request $request, User $user)
     {
         $this->authorize('edit', $user);
+
+        // name欄だけを検査するため、元のStoreUserクラス内のバリデーション・ルールからname欄のルールだけを取り出す。
+        $request->validate([
+            'name' => (new StoreUser())->rules()['name']
+        ]);

上のコントローラのupdateアクションでは、引数の型をStoreUserではなくRequestのままにしています。
StoreUserにすると、name欄、email欄、password欄の全てでバリデーション検査が実行されます。
しかし、現在の編集画面ではname欄しか変更できません。
name欄のみの入力値をバリデーションへ渡すと、email欄やpassword欄は空白であるとみなされ、必ず検査に失敗します。
そのため、フォームリクエスト・バリデーションに頼らず、$request->validateメソッドを使わなければなりません。
しかし、ルールを直に書くと管理が面倒なので、StoreUserのルールを流用しています。

ビューを修正する

resources/views/users/create.blade.php
         <div class="form-group">
             <label for="name">{{ __('Name') }}</label>
-            <input id="name" type="text" class="form-control" name="name" required autofocus>
+            <input id="name" type="text" class="form-control @if ($errors->has('name')) is-invalid @endif" name="name" value="{{ old('name') }}" required autofocus>
+            @if ($errors->has('name'))
+                <span class="invalid-feedback">{{ $errors->first('name') }}</span>
+            @endif
         </div>
         <div class="form-group">
             <label for="email">{{ __('Email') }}</label>
-            <input id="email" type="email" class="form-control" name="email" required>
+            <input id="email" type="email" class="form-control @if ($errors->has('email')) is-invalid @endif" name="email" value="{{ old('email') }}" required>
+            @if ($errors->has('email'))
+                <span class="invalid-feedback">{{ $errors->first('email') }}</span>
+            @endif
         </div>
         <div class="form-group">
             <label for="password">{{ __('Password') }}</label>
-            <input id="password" type="password" class="form-control" name="password" required>
+            <input id="password" type="password" class="form-control @if ($errors->has('password')) is-invalid @endif" name="password" required>
+            @if ($errors->has('password'))
+                <span class="invalid-feedback">{{ $errors->first('password') }}</span>
+            @endif
         </div>
resources/views/users/edit.blade.php
         <div class="form-group">
             <label for="name">{{ __('Name') }}</label>
-            <input id="name" type="text" class="form-control" name="name" value="{{ $user->name }}" required autofocus>
+            <input id="name" type="text" class="form-control @if ($errors->has('name')) is-invalid @endif" name="name" value="{{ old('name', $user->name) }}" required autofocus>
+            @if ($errors->has('name'))
+                <span class="invalid-feedback">{{ $errors->first('name') }}</span>
+            @endif
         </div>

カスタム属性名を追加する

resources/lang/ja/validation.php
     'attributes' => [
         'title' => __('Title'),
         'body' => __('Body'),
+        'name' => __('Name'),
+        'email' => __('Email'),
+        'password' => __('Password'),
     ],

Register用のルールと統合する

以前の記事で自動生成したログイン関連のファイルのうち、ユーザー登録を担当するRegisterコントローラにもUserのバリデーション・ルールが記載されています。
これを削除して、StoreUser内のルールを流用することで統一します。

app/Http/Controllers/Auth/RegisterController.php
    protected function validator(array $data)
    {
        // return Validator::make($data, [
        //     'name' => 'required|string|max:255',
        //     'email' => 'required|string|email|max:255|unique:users',
        //     'password' => 'required|string|min:6|confirmed',
        // ]);
        // 統一したバリデーション・ルールを用いる
        return Validator::make($data, (new \App\Http\Requests\StoreUser())->rules());
    }