[Laravel] FormRequestまとめ

#はじめに
基本含め、現場でよく使う関数をまとめたいと思います。
Laravelのバージョンは7.30.4です。

#目次

* rules()
* attributes()
* messages()
* validationData()
* prepareForValidation()
    * replace()
    * merge()
* withValidator()

#rules()

**バリデーションルールを定義する**関数です。

```php:app/Http/Requests/Example.php
public function rules()
{
    return [
        'name' => 'required|max:30',
    ];
}
```

```html
<input name="name" value="">
```

name属性の値である"name"フィールドに対して

* 必須(required)
* 最大30文字(max:30)

というバリデーションルールを定義しているということになります。

##attributes()
**バリデーション属性のカスタマイズを行う**関数です。
例えば、名前を入力するフォームがあったとします。
名前が必須項目である時、空文字のまま送信した場合、以下のようなエラーメッセージが出ました。
![スクリーンショット 2021-08-16 10.47.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1477513/2d76588f-65aa-b4e8-3bd5-13804334be3b.png)
この"name"は

```html
<input name="name" value="">
```

name属性の値である"name"です。
しかし、ほとんどの場合、"name"ではなく、項目名ここでは「名前」をエラーメッセージで出力したいと思います。
そのときに使うのが、このattributes()です。

````php:app/Http/Requests/Example.php
public function attributes()
{
    return [
        'name' => '名前',
    ];
}
```

すると、
![スクリーンショット 2021-08-16 11.02.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1477513/8ec7c858-cc75-3e5f-9dfb-4e9883b5cd98.png)
"name"が"名前"に変わり、項目名と一致させることができました！
「次はメッセージを修正したいんだけど？」って思いますよね。
そこで使うのが次に紹介するmessages()です。

#messages()
**エラーメッセージのカスタマイズを行う**関数です。
先ほどの"The 名前 field is required"を修正していきたいと思います。

````php:app/Http/Requests/Example.php
public function messages()
{
    return [
        'name.required' => '名前は必須です。',
    ];
}
```

このように「フィールド名.ルール」と書くことで、
![スクリーンショット 2021-08-16 11.36.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1477513/9414dc09-0e96-5bea-011d-765460d25314.png)
となります。
またattributes()でカスタマイズしたバリデーション属性、ここでは"名前"をリテラルではなく、変数のように扱いたい場合は

````php:app/Http/Requests/Example.php
public function messages()
{
    return [
        'name.required' => ':attributeは必須です。',
    ];
}
```

":attribute"を用います。
このようにすれば、attributes()でカスタマイズしたバリデーション属性を修正した場合でも、messages()を修正する必要がないので大変便利です。

#validationData()
**POSTデータの取得を行う**関数です。

````php:Illuminate/Foundation/Http/FormRequest.php
public function validationData()
{
    return $this->all();
}
```

お馴染みの$this->all()です。

#prepareForValidation()
**バリデーション前に何らかの処理を行っていることを示す**関数です。
POSTデータの加工で私はよく使用しています。
POSTデータの加工には、**置換を行うreplace()**や**新たなデータを追加するmerge()**などがあります。
対称的に、バリデーション後に何らかの処理を行うことを示す**passedValidation()**という関数もあります。
##replace()

```app/Http/Requests/Example.php
protected function prepareForValidation()
{
    $data = $this->validationData();
    
    if($data['send1'] == ''){
        // 置換後のデータ
        $data['send1'] = 'replaced';
    }

    $this->replace($data);
}
```

のようにしてデータの置換を行うことができます。

##merge()

```php:app/Http/Requests/Example.php
protected function prepareForValidation()
{
    $data = $this->validationData();
    // 追加したいデータ
    $data['add'] = 'added value';

    $this->merge($data);
}
```

のようにして新たなデータの追加を行うことができます。

#withValidator()
**自作のバリデーションを適用させたいときに用いる**関数です。


```app/Http/Requests/Example.php
public function withValidator($validator)
{
    /**
     * すでにバリデーションエラーがある場合に
     * 自作のバリデーションを適用させたくない時はこれを追加してあげる
     */ 
    if ($validator->fails()) {
        return;
    }

    $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add('field', 'エラーメッセージ');
        }
    });
}
```

#まとめ
コードを追いかけてみると、フォームリクエストにはたくさんの関数があることがわかるので、積極的に既存の関数を活用していきましょう！！！