IT-Q

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 を直接呼ぶことになります。