Laravelカスタムバリデーションの基礎と活用方法

## はじめに
今回はLaravelのカスタムバリデーションの基礎と活用方法について解説していこうと思います
Laravelのバリデーション機能は非常に強力ですが、プロジェクトの要件によってはカスタマイズが必要になることもあります
そんな時に作ると便利なカスタムバリデーションを活用してみましょう

## Laravelのバリデーション機能
まず、Laravelの基本的なバリデーションはデフォルトで多くのバリデーションルールを提供しています
例えば`required`、`integer`、`string`、`email`、`min`、`max`などの一般的なバリデーションルールがあります
これによりフォームデータの検証を簡単に行うことができます
```php
$request->validate([
  'name' => 'required|string|max:255',
  'email' => 'required|email',
  'age' => 'nullable|integer|min:18',
]);
```

## カスタムバリデーションルールの作成手順
### カスタムバリデーションルールクラスの作成
Laravelでは、artisanコマンドを使用して簡単にクラスを生成できます
```php
php artisan make:rule UpperCase // 入力値が大文字であることをチェックするバリデーション
```

このコマンドを実行することで下記の内容の`app\Rules\UpperCase.php`というファイルが作成されます

```php
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class UpperCase implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        //
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        //
    }
}
```

このファイルにカスタムルールのロジックを実装します
```php
namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{

    // コンストラクタは今回使用しないため削除

    
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return ':attribute must be uppercase.';
    }
}

```

### カスタムバリデーションルールの使用
カスタムバリデーションルールをフォームリクエストやコントローラで使用することができます

```FormRequest.php
use App\Rules\Uppercase;

// クラス名などは中略

public function rules()
{
  return [
    'name' => ['required','string','max:255', new Uppercase],
    'email' => 'required|email',
    'age' => 'nullable|integer|min:18',
  ];
}

```

```controller.php
use App\Rules\Uppercase;

// クラス名などは中略

$request->validate([
    'title' => ['required', new Uppercase],
]);

```

## カスタムバリデーションを利用した実際のコード例
先ほどのカスタムバリデーションを追加する場合は以下のように実装します

### フォームリクエストとコントローラに分ける場合

```Controller.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\FormRequest;

class UserController extends Controller
{
    public function store(FormRequest $request) // フォームリクエストの呼び出してバリデーションを実行させる
    {
        // バリデーション済みデータの取得
        $validated = $request->validated();

        // ユーザーの作成処理
        // User::create($validated);

        return response()->json(['message' => 'ユーザーが正常に作成されました。']);
    }
}
```

```FormRequest.php
use App\Rules\Uppercase;

    public function authorize()
    {
        return true; // 認可ロジックが必要な場合は適切に設定
    }

    public function rules()
    {
        return [
            'username' => ['required', new Uppercase], // カスタムバリデーションの適用
            'email' => 'required|email',
            'password' => 'required|min:8',
        ];
    }

    public function messages()
    {
        return [
            'username.required' => 'ユーザー名は必須です。',
            'email.required' => 'メールアドレスは必須です。',
            'email.email' => '有効なメールアドレスを入力してください。',
            'password.required' => 'パスワードは必須です。',
            'password.min' => 'パスワードは8文字以上でなければなりません。',
        ];
    }
```

### コントローラにまとめる場合
```php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Rules\Uppercase;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $request->validate([
            'username' => ['required', new Uppercase],
            'email' => 'required|email',
            'password' => 'required|min:8',
        ]);

        // ユーザーの作成処理
        // User::create($validated);

        return response()->json(['message' => 'ユーザーが正常に作成されました。']);
    }
}
```

上記のいずれかの方法でカスタムバリデーションを適用させることができます

## まとめ
Laravelのカスタムバリデーションは、デフォルトのバリデーションルールを超えて、アプリケーションのニーズに応じた柔軟な検証を可能にします
ぜひご自身の担当するプロジェクトにカスタムバリデーションを導入し、よりユースケースに合ったバリデーションを構築してみてください
今まで以上に堅牢なアプリケーションが実現できるでしょう

## 参考リンク

https://readouble.com/laravel/8.x/ja/validation.html

https://qiita.com/y2020/items/294f2318842a27656cbf