現在Laravelの教材を鋭意制作中です!完成まで今しばらくお待ちください

#22 FormRequest による分離設計

前章でご紹介したように、コントローラー内にバリデーションを直接記述する方法は、シンプルで理解しやすい反面、コード量が増えるにつれて複雑になりがちです。

特に複数のフォーム処理が絡んでくる場合、「どのバリデーションがどのフォームに属しているか」が分かりづらくなり、保守や再利用性の面で課題が出てきます。

そんなときに活躍するのが、Laravel の FormRequest クラスです。

FormRequest は、専用のリクエストクラスとしてバリデーションロジックを独立させ、コントローラーをすっきりさせる “分離設計” を可能にする強力な機能です。

それではFormRequestを作成していきましょう。

前章で切ったブランチをそのまま使用しますので、Git branchの切り出しはありません。

4. FormRequest による分離設計

php artisan make:request ContactRequest

このコマンドを使うことで、app/Http/Requests/ContactRequest.php が新しく作成されます。

バリデーション専用のリクエストクラス ContactRequest が生成され、このクラスは FormRequest を継承していて、以下のようなメソッドが含まれています。


public function authorize()
{
  return false; // このバリデーションを有効にしたい場合は true にする
}
public function rules()
{
  return [
    // バリデーションルールをここに記述
  ];
}

5.ContactRequestの実装

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ContactRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
  return true;
}


/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
/**
* バリデーションルールを定義するメソッド
*/
public function rules()
{
  return [
    'name' => 'required|string|max:255',
    'email' => 'required|email',
    'age' => 'required|integer|between:18,65',
    'gender' => 'required|in:男性,女性,その他',
    'interests' => 'nullable|array',
    'interests.*' => 'string',
    'message' => 'required|string|min:10|max:1000',
  ];
}

/**
* カスタムエラーメッセージ(任意)
*/
public function messages()
{
  return [
    'name.required' => 'お名前を入力してください。',
    'email.required' => 'メールアドレスを入力してください。',
    'email.email' => 'メールアドレスの形式が不正です。',
    'age.required' => '年齢を選択してください。',
    'age.integer' => '年齢は数値で入力してください。',
    'gender.required' => '性別を選択してください。',
    'message.required' => 'お問い合わせ内容を入力してください。',
    'message.min' => 'お問い合わせ内容は10文字以上で入力してください。',
    'message.max' => 'お問い合わせ内容は1000文字以内で入力してください。',
  ];
}
}

コードの解説

rules() には先ほどコントローラーに実装した validate を活用しますので、解説は省略します。

ですので、ここではエラーメッセージについて解説します。

Laravelのバリデーションでは「どの項目に」「どんなルールが適用されて」「何が間違っていたか」を明確に表現するため、以下のような形式を採用します。

return [
  'フィールド名.ルール名' => '表示したいメッセージ',
];

それぞれのルールから逸脱した際に、エラーメッセージが表示されるようになります。

エラーメッセージを変更する方法はほかにもありますが、こちらのFormRequestで設定する方法が一番わかりやすくてスマートです。

6.コントローラーの変更

せっかくFormRequestを使用してバリデーションの切り出しを行っても、FormRequestを反映させなければ全く意味がありません。

FormRequestの反映はControllerにて行いますので、コントローラーの編集をしましょう。

use App\Http\Requests\ContactRequest;

/* 中略 */

public function store(ContactRequest $request)
{
  // バリデーション済みデータを取得(安全に取り扱える)
  $data = $request->validated();

  // 配列 → カンマ区切り文字列へ変換(if文で処理)
  if (isset($data['interests']) && is_array($data['interests'])) {
    $data['interests'] = implode(',', $data['interests']);
  } else {
    $data['interests'] = null;
  }

  Contact::create($data);

  return redirect('/thanks');
}

コードの解説

use App\Http\Requests\ContactRequest;

これまではバリデーションにLaravelが用意する Request を使用していましたが、今回からは独自でFormRequest作成したのでこちらを使用します。

public function store(ContactRequest $request)

コントローラーでもっとも変更になったのがこの部分です。

Request $request だったものをContactRequest $requestへ変更します。

これにより、先ほど作成したFormRequestの内容が適用されます。

7.thanksページの作成

フォームのバリデーションも無事に通過してデータを登録することができたら、データを送信したユーザーに対して、データが無事に送信できたかどうかを知らせるthanksページを作成しましょう。


@extends('layouts.app')

@section('title', '送信完了')

@section('content')
<h2>お問い合わせありがとうございます</h2>

<p>ご入力いただいた内容は正常に送信されました。</p>
<p>担当者より折り返しご連絡いたしますので、しばらくお待ちください。</p>

<br>

<a href="/">トップページへ戻る</a>
@endsection

thanksページは特段の関数などはなく、ただの静的なページとなっています。

8.Git push

以上が完了したら、ここでGitを共有しておきましょう。

git add -A
git commit -m "コメントを入力する"
git push origin make-validate

git pushが無事完了したら、GitHub上で操作を行います。

pull requestが来ているので、mergeしましょう。

次章:#23 old()の役割 に進む