エンジニ屋.com(エンジニヤドットコム)

分かりやすくを意識して情報発信!

【Laravel】オリジナルのバリデーション(ファイル名重複)を作成する方法【汎用的】


本記事は、ファイル名をデータベース内のデータと重複させないようにするバリデーションを作成する方法を紹介します。

ファイルサイズやマイムタイプのバリデーションが用意されていますが、ファイル名のバリデーションは用意されていないので、自信でカスタムして作成する必要があります。

それでは実装していきましょう!

前提

  1. filesテーブルが存在

  2. テーブルにfile_nameというファイル名を保存するカラムが存在

  3. ModelのFile.phpが存在

Rulesディレクトリにバリデーションルールのファイルを作成

先ずはruleのファイルをコマンドで作成します。

php artisan make:rule FileNameUnique

ここではファイル名をFileNameUniqueとしますが、何でも良いです。

受け取った値をバリデートする処理を記述します。

app\Rules\FileNameUnique.php

public function passes($attribute, $value)
    {
        if( $value === null ){
            return true;
        }

        $fileName = $value->getClientOriginalName();
        
        $qb = File::where('file_name', $fileName);
        if ($qb->exists()) {
           return false;
        }

        return true;
    }

public function message()
    {
        return '既に同じファイル名で登録されています';
    }

解説

引数の$valueでフォームから送信された値が受け取れます。

今回は使いませんが、引数の$attributeはフォームで送信されるnameの値を受け取れます。

$value === nullで値が空の場合は、そのまま何も処理せずに返しています。

空の場合にエラーを返すバリデーションを書いても良いですが、requiredで用意されているのでそちらをあとで使うようにします。

$fileNameの変数にgetClientOriginalNameメソッドでフォームから受け取ったファイル情報からファイル名を取得して格納します。

$qbの変数にElquentでfileテーブルに同じファイル名をwhereを取得するクエリ文を格納します。

if ($qb->exists())でレコードが存在するチェックしています。

もし存在していたらと重複しているということなので、ifの中を通ってreturn falseを返します。

falseを返すとエラーメッセージを呼び出します。

messageメソッドの中にエラー文を記述します。

これでバリデーションのクラスの作成は完了です。

こちらを呼び出す処理を記述していきます。

Requestファイル内でルールを呼び出す

記述箇所はControllでも良いですし、requestファイルに他のもまとめて記述する方法があります。

ここではrequestファイルに記述していきます。

コマンドで下記を実行

php artisan make:request FileInputRequest

末尾のファイル名は自分の構成に合うファイル名に変えて下さい。

app\Http\Requests\FileInputRequest.php

use App\Rules\FileNameUnique;

public function rules()
    {
        return [
            'upload' => [new FileNameUnique,'required'],
        ];
 }

解説

use で先ほど作成したバリデーションルールのファイルを呼び出したら、該当の箇所にnew でインスタンスを記述します。

これでオッケーです。

必須のバリデーション(required)も加えておきます。

表側とコントローラーも一応載せておきます。

resources\views\file\edit.blade.php

<div>
      <label for="upload">ファイルアップロード</label>
         {{ Form::file('upload') }}
        @if ($errors->has('upload'))
          <p class="error_msg">{{ $errors->first('upload') }}</p>
        @endif
 </div>

app\Http\Controllers\Admin\FileController.php

 public function edit()
    {
  //処理を記述

        return view('file.edit');
    }

public function store(FileInputRequest $request) //メソッドの引数でRequest classをインスタンス化
    {
     $inputs = $request->all();
  
     //処理を記述

    return view('file.edit');
}

本来は間に処理を色々と入れますが、表示とフォーム送信するだけの必要最低限のソースのみ記述しています。

以上でカスタムバリデーションの作成から表示まで完了です。 お疲れ様です!