FormRequest に寄せると困る場面はありますか。
作成と更新でルールが変わる場合です。更新では unique から自分自身を除外する必要があり、同じクラスを使い回すと分岐だらけになります。除外は Rule::unique の ignore で書けます。
面接官が見ているのは一つのやり方を盲信していないか。
これは「バリデーションの置き場所として基本になるのはどれですか。」への追撃質問です。
よくある答えと、面談でどう見られるか
- 作成と更新でルールが変わる場合。unique の自己除外などで分岐が増える
その通りです。素直に StoreXxxRequest と UpdateXxxRequest に分ける方が読みやすい。バッチやキューから使いたい場合も、HTTP 前提なので使えません。 - ルールが複雑になると FormRequest では書けなくなる
クロージャルールやカスタムルールで表現できます。 - FormRequest は1つのコントローラでしか使えない
複数から使えます。 - FormRequest を使うとエラーメッセージを日本語にできない
messages() で自由に定義できます。
面接官は何を見ているか
- 同じ入力でも文脈でルールが変わる場合を挙げた
- 作成と更新でルールが異なる問題に触れた
- 条件付きルール(sometimes / rule closure)や分割で対処すると言えた
模範解答
作成と更新でルールが変わる場合です。更新では unique から自分自身を除外する必要があり、同じ FormRequest を使い回すと分岐だらけになります。なおその除外は Rule::unique('users')->ignore($user) と書きますが、ここに渡してよいのはモデルから取った ID だけです。リクエストから来た値をそのまま渡すと SQL インジェクションになる、と公式が明示的に警告しています。素直に StoreXxxRequest と UpdateXxxRequest に分けるのが読みやすい。あとは、コントローラ以外(バッチやキュージョブ)から同じ検証をしたい場合、FormRequest は HTTP リクエスト前提なので使えず、Validator を直接呼ぶことになります。