やりたいこと
-
例えば、WEBサイトの新規登録画面を作る状況で、郵便番号などを整形した上でDBへ登録したい時
-
Laravelを使うとなると、ベストプラクティスにもある通りフォームリクエストを使うことが多いと思うので、
Viewから入力内容を含んだリクエストを送信
↓
フォームリクエストでバリデーション
↓
Contorollerでバリデーション済のリクエスト受け取り
↓
受け取ったリクエストに対して整形・・・★
みたいにやると思うが★の部分でControllerを汚すため、あまり望ましくないと思う
ということで今回のらやりたいことは「やりたいこと」は
「Controllerを汚さずにバリデーション済かつ、整形済みの値を取得する」
です。
手段
方法としては
- 同じController内で整形用フォーム作る
- 別階層に整形専用クラスを作成、使用
などいくつか方法はあるけど、自分の場合は
- passedValidationメソッドを使う
という選択肢を使った次第
内容
-
passedValidation
の説明は公式ドキュメントになくて、Githubから引用
使い方
- フォームリクエストに
passedValidation
メソッドを追加し、バリデーション後の処理を書くだけ。非常に簡単。
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class HogeRequest extends FormRequest
{
...
...
// 郵便番号の整形(ハイフンが有ったらハイフン削除)
public function passedValidation()
{
if (Str::contains($this->postal_code, '-')) {
$formattedPostalCode = Str::remove('-', $this->postal_code);
$this->merge([
'postal_code' => $formattedPostalCode,
]);
}
}
}
注意点
- 一個厄介なのが、フォームリクエストでControllerで整形後の内容は
$request
には反映されるが、$request→validated()
には反映されない点- リクエストの値がバリデーションを通っていることを明示的にするため、
$request→validated()
を使うことが多いと思うが、これでは整形前(=入力値そのまま)しか取得できない
- リクエストの値がバリデーションを通っていることを明示的にするため、
↓HogeRequestでフォームリクエスト受け取り先Controller
class HogeController extends Controller
{
public function register(HogeRequest $request)
{
$validated = $request->validated();
dd($validated); // 整形前(=ハイフン未削除)の値
dd($request); // 整形後(=ハイフン削除済)の値
}
}
- なので、整形後の値を取得する方法は2つ
- 1,
$request
をそのまま使う - 2, 以下のように
$validated = $request→validated()
した後、$validated
の内容を$request
に置き換える
- 1,
$validated = $request->validated();
// passedValidationで整形後の値で置き換え
$validated['postal_code'] = $request->postal_code;
これはこれでビジネスロジック汚すので、別で専用メソッド作って呼び出すとかのがいいかもですね
protected function ($request)
{
$validated = $request->validated();
// passedValidationで整形後の値で置き換え
$validated['postal_code'] = $request->postal_code;
// 他に整形が必要なリクエスト値も置換え
...
...
return $validated;
}
尚、こことか
こことか
見ていると$request
に対してvalidated()
を使うのは暗黙的なベストプラクティスに思われます。
補足
-
passedValidation
の逆にバリデーション前にリクエスト処理を行えるメソッドとして、prepareForValidation
がある - これもドキュメントには記載がないが、Githubを転記
- いつ使うんだろう。。。
所見
- ココまで書いて思うのは、自分のアサイン中のプロジェクトは
validated()
は基本必須なので、一番スマートなのは「別階層に整形専用クラスを作成、使用」かな、と思いました。。。- Controllerで専用クラスを呼び出して、1文で整形してしまうみたいな感じかな
- 例えば、専用クラス名が
ViewHelper
でメソッド名がformatPostalCode
であればこんな感じ
- 例えば、専用クラス名が
- Controllerで専用クラスを呼び出して、1文で整形してしまうみたいな感じかな
public function register(HogeRequest $request)
{
// 郵便番号の整形
ViewHelper::formatPostalCode($request->postalcode);
...
}
こっちのがControllerで余計な処理($vaidated
に$request
を再代入など)をしなくていいのでスッキリする。
しかも整形処理なんて、新規登録だけじゃなくて、登録情報変更でも使ったりする汎用性の高い処理なので、そっちのが望ましい
-
でも、プロジェクトとして
$request
そのまま使うことを許容されているのであれば、断然こっちのが楽ですね -
公式ドキュメントに書いていない理由の個人的推測は、Laravelベンダーとしては
$request→validated()
推奨・・・★↓
「
$request→validated()
ではpassedValidation
メソッドで処理後の値を取得できない」↓
「★と相性悪いよね。。。」
ってとこでしょうね。
最後までお読みいただきありがとうございました!