【Laravel/Form Reques】 フォームリクエストでよく使う機能まとめ

Laravel のフォームリクエストは、リクエストのバリデーションや認可処理を専用のクラスに切り出すことができる非常に便利な仕組みです。  
この記事では、フォームリクエストでよく使われる機能やテクニックを実例とともに解説します。

---

## 目次

- [フォームリクエストの基本](#フォームリクエストの基本)
- [認可（Authorize）メソッド](#認可authorize-メソッド)
- [バリデーションルールの定義](#バリデーションルールの定義)
- [カスタムエラーメッセージ](#カスタムエラーメッセージ)
- [入力データの前処理（prepareForValidation）](#入力データの前処理prepareforvalidation)
- [失敗時のカスタム処理](#失敗時のカスタム処理)
- [まとめ](#まとめ)

---

## フォームリクエストの基本

フォームリクエストは、`php artisan make:request SampleRequest` で作成でき、コントローラにタイプヒントとして注入することで自動的にバリデーションが実行されます。  
例えば、以下のようなフォームリクエストクラスを作成します。

```php
// app/Http/Requests/SampleRequest.php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SampleRequest extends FormRequest
{
    /**
     * 認可（Authorization）処理
     */
    public function authorize(): bool
    {
        // 認可ロジック。ここでは常に true を返して全ユーザーに許可
        return true;
    }

    /**
     * バリデーションルールの定義
     */
    public function rules(): array
    {
        return [
            'title'   => 'required|string|max:255',
            'content' => 'required|string',
        ];
    }
}
```

コントローラ側では、このフォームリクエストをインジェクトするだけで、バリデーションが自動で適用されます。

```php
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;

use App\Http\Requests\SampleRequest;
use App\Models\Post;

class PostController extends Controller
{
    public function store(SampleRequest $request)
    {
        // バリデーション済みのデータを取得
        $validated = $request->validated();

        // Eloquent を使った登録処理
        Post::create($validated);

        return redirect()->route('posts.index');
    }
}
```

---

## 認可 (Authorize) メソッド

`authorize()` メソッドは、リクエストがその操作を実行する権限を持つかどうかを判定するために使用します。  
ここではユーザーのロールや権限に応じたチェックを行うことができます。

```php
public function authorize(): bool
{
    // 例: 管理者のみが投稿を作成できる
    return auth()->check() && auth()->user()->isAdmin();
}
```

認可に失敗した場合は、403 Forbidden が自動で返されます。

---

## バリデーションルールの定義

`rules()` メソッド内で、フォームリクエストごとにバリデーションルールを定義します。  
ルールは文字列や配列形式で指定でき、複数のルールを組み合わせることができます。

```php
public function rules(): array
{
    return [
        'title'   => ['required', 'string', 'max:255'],
        'content' => ['required', 'string'],
        'tags'    => ['nullable', 'array'],
        'tags.*'  => ['string', 'distinct'],  // tags配列内の各要素に対して
    ];
}
```

---

## カスタムエラーメッセージ

フォームリクエストでは、`messages()` メソッドを使って各バリデーションルールに対するカスタムエラーメッセージを定義できます。

```php
public function messages(): array
{
    return [
        'title.required' => 'タイトルは必須項目です。',
        'title.max'      => 'タイトルは:max文字以内で入力してください。',
        'content.required' => 'コンテンツを入力してください。',
    ];
}
```

これにより、ユーザーに対してよりわかりやすいエラーメッセージを提供できます。

---

## 入力データの前処理 (prepareForValidation)

`prepareForValidation()` メソッドをオーバーライドすることで、バリデーションが実行される前に入力データを加工・正規化することができます。  
例えば、メールアドレスを小文字に変換する場合は以下のようにします。

```php
protected function prepareForValidation(): void
{
    $this->merge([
        'email' => strtolower($this->input('email')),
    ]);
}
```

これにより、ユーザーが大文字で入力したメールアドレスも正しくバリデーションできるようになります。

---

## 失敗時のカスタム処理

フォームリクエストのバリデーションが失敗した際に、独自のレスポンスを返したい場合は、`failedValidation()` をオーバーライドします。  
ただし、このメソッドをカスタマイズする場合は、`Illuminate\Contracts\Validation\Validator` を利用してエラーメッセージを構築し、`HttpResponseException` を投げる必要があります。

```php
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

protected function failedValidation(Validator $validator)
{
    // エラー内容を JSON 形式で返す例
    throw new HttpResponseException(response()->json([
        'status' => 'error',
        'errors' => $validator->errors(),
    ], 422));
}
```

※ 注意: API など、フロントエンド側でバリデーションエラーのハンドリングを行いたい場合に有効です。

---

## まとめ

フォームリクエストは、Laravel でバリデーションや認可処理をシンプルに管理できる強力な機能です。  
この記事では、以下の機能について解説しました。

- **認可 (authorize)**  
  → ユーザーの権限チェックを行う

- **バリデーションルールの定義 (rules)**  
  → 入力項目ごとにルールを設定

- **カスタムエラーメッセージ (messages)**  
  → ユーザー向けにわかりやすいエラーメッセージを提供

- **入力データの前処理 (prepareForValidation)**  
  → バリデーション前にデータを加工

- **失敗時のカスタム処理 (failedValidation)**  
  → バリデーションエラー時に独自のレスポンスを返す

これらの機能を活用することで、より堅牢でメンテナンスしやすいコードを実現できます。  
ぜひ、実際のプロジェクトでフォームリクエストを上手く活用してみてください！

---

#### 参考リンク

- [Laravel 公式ドキュメント - Form Requests](https://laravel.com/docs/11.x/validation#form-request-validation)
- [Laravel 公式ドキュメント - Validation](https://laravel.com/docs/11.x/validation)

---

以上、フォームリクエストでよく使う機能についてのまとめでした。  
皆さんの開発の参考になれば幸いです。