【Laravel6.x】バリデーションの手順

## 問題
Laravelでバリデーションを行いたい！

## 手順
①クラス作成
②ルール作成
③バリデーションメッセージ表示
④old関数
⑤日本語化

### ①クラス作成→バリデーション条件設定→適用
```
ターミナル

php artisan make:request CreateDate
```
ファイルが「App/Http/Request」内で生成される。

#### ※ポイント
クラスはバリデーションの種類ごとに作成する。

例）
①予算作成フォームで「タイトル / 金額 / 日付」のバリデーションを行う
②支出作成フォームで「タイトル / 金額 / 日付」のバリデーションを行う
③プロフィール編集フォームで「画像」のバリデーションを行う

上記3箇所でバリデーションを行いたい場合、
①と②は同じバリデーション内容なので1つのクラスを作成して2箇所に適用すれば良いが
③は全く異なるバリデーション内容となるため別のクラスを作成して適用させる。

要するに
#### バリデーション内容が異なる場合は1クラスにバリデーション内容をまとめて適用されることは出来ない。
理由はバリデーション内容とフォームのname属性が 「完全一致」 でないとエラーになるため。

以下のようにクラスを分けて、
それぞれにバリデーション内容を記載していく↓
```
ターミナル
例

// ①と②用
php artisan make:request CreateDate

// ③用
php artisan make:request CreateFile
```

### ②ルール作成
```App/Http/Request/CreateDate.php
public function authorize()
{
    // ⭐️authorize = 権限関係の処理を記述する
    // 　　「ログインユーザーがこのリクエストを実行する権限があるか否か」の条件を記述する
    // 認証の切り分けを行わない場合はtrue(常に通す)で良い
    return true;
}

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        // ⭐️rules = フォームバリデーション内容を記載

        // ⭐️「=>の左側」は、formのinputの「name属性」と一致させる
        //   「=>の右側」は、条件を設定
        // amount条件 = 必須|整数|11桁の99999999999まで
        'amount' => 'required|integer|max:99999999999',
        // title条件 = 必須|20文字まで
        'title' => 'required|max:20',
        // date条件 = 必須|日付のみ
        'date' => 'required|date',
    ];
}
```
#### バリデーションルールの一例
https://qiita.com/tatun55/items/67b0f6b8f269b2fd829d#1-4-%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%AB%E3%83%BC%E3%83%AB

#### 画像のバリデーション例
```
public function authorize()
{
    return true;
}

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        // file条件 = 必須|画像ファイルであること|拡張子の指定|サイズの指定
        'file' => 'required|file|mimes:jpeg,png,jpg,webp|max:2048',
    ];
}
```

参考サイト

https://qiita.com/Charry/items/51eb583f835c79858937

### フォームにルールを適用させる
```SpendingController.php
public function store(Request $request) {
    // 省略
}
↓
↓適用させると
↓                  
↓⭐️
public function store(CreateData $request) {
    // 省略
}
```

これでバリデーションはOK！

### ③バリデーションメッセージ表示
#### 個別でバリデーションメッセージを表示する場合
![スクリーンショット 2024-04-25 10.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/083b5e66-4d17-8d01-2489-6fa8ce0efcf8.png)
```create.blade.php
<form action="{{ route('spending.store') }}" method="post" class="mt-5 date_option">
    @csrf
    <div class="form-group">
        <label for="date">日付</label>
        <input type="date" id="date" name="date" class="date_border form-control" value="{{ old('date') }}">
        <!-- ↓⭐️バリデーションエラー個別表示 -->
        @error('date')
            <div class="text-danger"><span>{{ $message }}</span></div>
        @enderror
    </div>
    <div class="form-group">
        <label for="title">タイトル(20文字以内)</label>
        <input type="text" class="form-control" id="title" name="title" placeholder="予算のタイトルを入力" value="{{ old('title') }}">
        <!-- ↓⭐️バリデーションエラー個別表示 -->
        @error('title')
            <div class="text-danger"><span>{{ $message }}</span></div>
        @enderror
    </div>
    <div class="form-group">
        <label for="amount">支出金額(11桁以内)</label>
        <input type="number" class="form-control" id="amount" name="amount" placeholder="支出金額を入力" value="{{ old('amount') }}">
        <!-- ↓⭐️バリデーションエラー個別表示 -->
        @error('amount')
            <div class="text-danger"><span>{{ $message }}</span></div>
        @enderror
    </div>
    <div class="mt-4">
        <button type="submit" class="btn btn-primary">支出を登録</button>
    </div>
</form>
```
参考サイト↓

https://laranote.jp/laravel-blade-display-validation-errors/

#### まとめて1箇所にバリデーションメッセージを表示する場合
![スクリーンショット 2024-04-25 10.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/0263b811-20df-a5ae-1dc4-399c3c1a085a.png)
```create.blade.php
<!-- まとめてバリデーションメッセージを表示 -->
<div class="pandel-body">
    @if($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach($errors->all() as $messsage)
            <li>{{ $messsage }}</li>
            @endforeach
        </ul>
    </div>
    @endif
</div>
<form action="{{ route('spending.store') }}" method="post" class="mt-5 date_option">
    // 省略
</form>
```

### ④old関数
バリデーションエラーでリダイレクト時に入力値が消えてしまうの不便
例)
タイトル、金額は合っているのに、日付を入力し忘れたら、
デフォルトではタイトル、金額の入力が消えてしまう。
ユーザー視点だと再入力は大変めんどくさい。
↓
バリデーションで引っかかっても入力値の保持させる　= old関数

```create.blade.php
<form action="{{ route('spending.store') }}" method="post" class="mt-5 date_option">
    @csrf
    <div class="form-group">
        <label for="date">日付</label>
        //⭐️↓ここ ⭐️old('name属性')
        <input value="{{ old('date') }}" type="date" id="date" name="date" class="date_border form-control">
        <!-- バリデーション個別表示 -->
        @error('date')
            <div class="text-danger"><span>{{ $message }}</span></div>
        @enderror
    </div>
    <div class="form-group">
        <label for="title">タイトル(20文字以内)</label>
        //⭐️↓ここ
        <input value="{{ old('title') }}" type="text" class="form-control" id="title" name="title" placeholder="予算のタイトルを入力">
        <!-- バリデーション個別表示 -->
        @error('title')
            <div class="text-danger"><span>{{ $message }}</span></div>
        @enderror
    </div>
    <div class="form-group">
        <label for="amount">支出金額(11桁以内)</label>
        //⭐️↓ここ
        <input value="{{ old('amount') }}" type="number" class="form-control" id="amount" name="amount" placeholder="支出金額を入力">
        <!-- バリデーション個別表示 -->
        @error('amount')
            <div class="text-danger"><span>{{ $message }}</span></div>
        @enderror
    </div>
```

### ⑤日本語化
#### 日本語化の設定
バリデーションメッセージデフォルト = 英語
これを日本語に変更する

「resorces/lang」はデフォルトで「resorces/lang/en」しかない
①「resorces/lang」フォルダに「resorces/lang/ja」を作成する
②「resorces/lang/jaファイル」に「resorces/lang/en」をコピペする
③「config/app.php」に以下を追記する
```config/app.php
// ここから
'timezone' => 'Asia/Tokyo',     // タイムゾーン
'locale' => 'ja',               // 第一言語を日本語（ローカライゼーション）
'fallback_locale' => 'en',      // 該当言語が見つからない場合の言語
'faker_locale' => 'ja_JP',
// ここまで追記


'aliases' => [
// 省略
```

特に以下だけは必須
理由は「resorces/lang/ja」を参照させるため
```config/app.php
'locale' => 'ja',
```

#### 任意のメッセージを日本語化
「resorces/lang/ja/validation.php」の「return」の中を日本語にしていく
##### 一例
![スクリーンショット 2024-04-25 10.58.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/62cbc680-c58a-88c9-40a2-a8aa041dc5bb.png)
![スクリーンショット 2024-04-25 10.58.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/bdce39f4-704c-8343-ef58-552ee736cd23.png)
![スクリーンショット 2024-04-25 10.58.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/4a552a0e-142d-ad98-6600-78fd63ffb88f.png)
![スクリーンショット 2024-04-25 10.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/e3e49767-b60b-5a15-49fe-e8fb83105a21.png)
![スクリーンショット 2024-04-25 10.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/fc2a3bf5-014f-016b-dd00-417260506bc8.png)

##### :attributeの修正
下の方にある:attribute部分を修正する
デフォルト「:attribute」 = name属性がそのまま入る
例)上の画像の1つ目で言えば以下のようになってしまう
```
'image' => '「:attribute」は画像にしてください。',
↓
「file」は画像にしてください。
(fileがname属性)
```

だから'attributes'配列内を
name => ‘表示名となるように修正していく。

```resorces/lang/ja/validation.php
'attributes' => [
    'email'=>'メールアドレス',
    'password'=>'パスワード',
    'amount'=>'金額',
    'title'=>'タイトル',
    'date'=>'日付',
    'file'=>'ファイル',
],
```

こうすることで以下のように日本語にできる
```
'image' => '「:attribute」は画像にしてください。',
↓
「ファイル」は画像にしてください。
```

## 参考サイトまとめ
https://qiita.com/tatun55/items/67b0f6b8f269b2fd829d#1-4-%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%AB%E3%83%BC%E3%83%AB

https://qiita.com/Charry/items/51eb583f835c79858937

https://laranote.jp/laravel-blade-display-validation-errors/

https://codelikes.com/laravel-file-upload/


## 番外編
### authのバリデーション手順
このページ終了後の続き

https://qiita.com/honaki/items/273f330cb0aafe5b792a