[Laravel]リクエスト値の整形にpassedValidationという選択肢

# やりたいこと

- 例えば、WEBサイトの新規登録画面を作る状況で、郵便番号などを整形した上でDBへ登録したい時
- Laravelを使うとなると、[ベストプラクティス]([https://github.com/alexeymezenin/laravel-best-practices/blob/master/japanese.md#バリデーション](https://github.com/alexeymezenin/laravel-best-practices/blob/master/japanese.md#%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3))にもある通りフォームリクエストを使うことが多いと思うので、
    
    Viewから入力内容を含んだリクエストを送信
    
    ↓
    
    フォームリクエストでバリデーション
    
    ↓
    
    Contorollerでバリデーション済のリクエスト受け取り
    
    ↓
    
    受け取ったリクエストに対して整形・・・★
    

みたいにやると思うが★の部分でControllerを汚すため、あまり望ましくないと思う

ということで今回のらやりたいことは「やりたいこと」は

**「Controllerを汚さずにバリデーション済かつ、整形済みの値を取得する」**

です。

## 手段

方法としては

- 同じController内で整形用フォーム作る
- 別階層に整形専用クラスを作成、使用

などいくつか方法はあるけど、自分の場合は

- passedValidationメソッドを使う

という選択肢を使った次第

# 内容

- `passedValidation`の説明は公式ドキュメントになくて、Githubから引用

https://github.com/laravel/framework/blob/b5300a1dba04614542c3eb2b342f5c07a89c4162/tests/Foundation/FoundationFormRequestTest.php#L334

## 使い方

- フォームリクエストに`passedValidation`メソッドを追加し、バリデーション後の処理を書くだけ。非常に簡単。

```php
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

```php
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`に置き換える

```php
        $validated = $request->validated();
        // passedValidationで整形後の値で置き換え
        $validated['postal_code'] = $request->postal_code;
```

これはこれでビジネスロジック汚すので、別で専用メソッド作って呼び出すとかのがいいかもですね

```php
    protected function ($request)
    {
        $validated = $request->validated();
        // passedValidationで整形後の値で置き換え
        $validated['postal_code'] = $request->postal_code;
				// 他に整形が必要なリクエスト値も置換え
				...
				...

        return $validated;
    }
```

尚、こことか

https://github.com/alexeymezenin/laravel-best-practices/blob/master/japanese.md#new%E3%81%AE%E4%BB%A3%E3%82%8F%E3%82%8A%E3%81%ABioc%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%82%82%E3%81%97%E3%81%8F%E3%81%AF%E3%83%95%E3%82%A1%E3%82%B5%E3%83%BC%E3%83%89%E3%82%92%E4%BD%BF%E3%81%86

こことか

https://github.com/alexeymezenin/laravel-best-practices/blob/master/japanese.md#%E3%83%9E%E3%82%B9%E3%82%A2%E3%82%B5%E3%82%A4%E3%83%B3%E3%83%A1%E3%83%B3%E3%83%88

見ていると`$request`に対して`validated()`を使うのは暗黙的なベストプラクティスに思われます。

## 補足

- `passedValidation`の逆にバリデーション前にリクエスト処理を行えるメソッドとして、`prepareForValidation`がある
- これもドキュメントには記載がないが、Githubを転記
    - いつ使うんだろう。。。

https://github.com/laravel/framework/blob/b5300a1dba04614542c3eb2b342f5c07a89c4162/tests/Foundation/FoundationFormRequestTest.php#L329

# 所見

- ココまで書いて思うのは、自分のアサイン中のプロジェクトは`validated()`は基本必須なので、一番スマートなのは「別階層に整形専用クラスを作成、使用」かな、と思いました。。。
    - Controllerで専用クラスを呼び出して、1文で整形してしまうみたいな感じかな
        - 例えば、専用クラス名が`ViewHelper`でメソッド名が`formatPostalCode`であればこんな感じ

```php
	public function register(HogeRequest $request)
    {
			// 郵便番号の整形
			ViewHelper::formatPostalCode($request->postalcode);
			...
    }
```

こっちのがControllerで余計な処理（`$vaidated`に`$request`を再代入など）をしなくていいのでスッキリする。

しかも整形処理なんて、新規登録だけじゃなくて、登録情報変更でも使ったりする汎用性の高い処理なので、そっちのが望ましい

- でも、プロジェクトとして`$request`そのまま使うことを許容されているのであれば、断然こっちのが楽ですね

- 公式ドキュメントに書いていない理由の個人的推測は、Laravelベンダーとしては
    
    `$request→validated()`推奨・・・★
    
    ↓
    
    「`$request→validated()`では`passedValidation`メソッドで処理後の値を取得できない」
    
    ↓
    
    「★と相性悪いよね。。。」
    

ってとこでしょうね。

最後までお読みいただきありがとうございました！