1
0

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 3 years have passed since last update.

[laravel]個人的バリデーションの書き方

Last updated at Posted at 2021-02-07

こんにちは!

この間laravelでファイルアップロード処理を含む保存処理のバリデーションの実装をしていたときに、バリデーションエラー時にアップロードしたファイルのデータがなくなってしまうので、ファイルアップロード以外のバリデーションエラー時にアップロードしたファイルを仮アップロードしてからリダイレクトという実装をしました。

まぁカスタムバリデートを実装すればいいことですが、フォームリクエストバリデーションの中でアップロードの処理をするのも変な感じがするし、かと言ってコントローラにValidatorのロジックを書くとコントローラ内が冗長になるし、アクションごとにフォームリクエストバリデーションとコントローラでのバリデーションを切り替えるのも気持ちが悪い

なんかなるべく共通した書き方できないかなーと感じて個人的にしっくりきた書き方を紹介したいと思います!

結論を先に書くとバリデーションクラスを作ってValidatorインスタンスを返す処理を実装します

コードはユーザーの名前とアイコン画像の編集を実装すると仮定します

route

web.php
Route::post('user/update', 'UserController@update')->name('user.update');

view

<form action="{{route('user.update')}}" method="post" enctype="multipart/form-data">
    @csrf
    <input type="text" name="name">
    <input type="file" name="file">
</form>

Validator

UserValidator.php
<?php

namespace App\Http\Validator;

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

class UserValidator
{
    public function createValidation(Request $request): \Illuminate\Contracts\Validation\Validator
    {
        $params = $request->all();
        return Validator::make($params, [// <- バリデーターインスタンスを返す
            'name' => [
                'required',
            ],
            'file' => [
                'file',
                'image',
                'mimes:jpeg,jpg,png,gif',
                'max:5120',
            ],
        ], [
            'name' => '入力されていません。',
            'file.file' => '不正なファイルです。',
            'file.image' => '画像以外のデータが送信されました。',
            'file.mimes' => '登録できる拡張子はjpeg,jpg,png,gifのいずれかになります。',
            'file.max' => '画像サイズが大きすぎます。',
        ])->after(function ($validator) use ($params) {
            //...カスタムバリデーション
            $validator->errors()->add('name', 'エラー!');
        });
    }
}

controller

UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Validator\UserValidator;

class UserController extends Controller
{
    privare $userValidator;

    public function __construct(UserValidator $userValidator)
    {
        $this->userValidator = $userValidator;
    }
    public function update(Request $request)
    {
        $validator = $this->userValidator->updateValidation($request);
        $validator->validate();//@todo バリデーションエラー時に即リダイレクト
        //or
        if ($validator->fails()) {
            //@todo バリデーションに引っかかったフィールド名を取得(ここもっと分かり易いやり方方法ないのかな?)
            $messageBag = $validator->messages();
            $error_messages = $messageBag->getMessages();
            if (!array_key_exists('file', $error_messages)) {
                //@todo nameフィールドでバリデート引っかかったけどfileフィールドは通過した時の処理(仮ファイルアップロードの処理など)
                //...
            }
            //@todo バリデーションエラーと入力したデータを持ってリダイレクト
       return redirect()
                ->route('user.edit')
                ->withErrors($validator)
                ->withInput();
        }
        //@todo バリデーション通過時の処理
        ...
        return redirect()->route('user.edit');
    }
}

こうすれば即リダイレクトと処理を挟んでリダイレクトが簡単に切り替えられるし、そこまで冗長じゃないし、あと他の人がコントローラを見たとき何がしたいのかよくわかるのかなーと

まぁsymfonyのhandleRequestに近づけた感じです

参考にしてください!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?