今回は、またしても新規のLaravelのバージョン対しての私のキャッチアップの話です。もちろん、存在は知っていたのですが、最近まで使用する機会がありませんでした。ブレードで使われる@errorの話なのですが、調べたら登場したのはなんとLaravelバージョン5.8、現在のバージョンが8.xなので遠い昔のように思えます。しかし、5.8がリリースされたのはつい去年のことです。Laravelのバージョン形態が変わってから、どんどん更新が早まっていくように感じられます。
@if vs @error
まず、バリデーションエラー表示において、どう@ifから@errorへ進化したかを比較してみます。
@ifを使用すると、
<label for="title">投稿のタイトル</label>
<input id="title" type="text" class="@if ($errors->has('title') is-invalid @endif">
@if ($errors->has('title')
<div class="alert alert-danger">{{ $errors->first('title') }}</div>
@endif
これが、@errorを使用すると、
<label for="title">投稿のタイトル</label>
<input id="title" type="text" class="@error('title') is-invalid @enderror">
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
両者とも意味は同じですが、@errorの方がすっきりして意味がわかりやすいですね。
配列の入力があるフォームで@error
さて、先の例と違って、以下のような配列フォームではどう@errorを使うことができるでしょう?

まず、エラー表示のもととなるコントローラのバリデーションは、
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FormController extends Controller
{
public function create()
{
return view('form.create');
}
public function store(Request $request)
{
$rules = [
'name.*' => 'nullable',
'price.*' => 'nullable|required_with:name.*|integer|gt:0',
];
$messages = [
'price.*.required_with' => '入力してください',
'price.*.integer' => '整数で入力してください',
'price.*.gt' => '0超の整数で入力してください',
];
$validated = $request->validate($rules, $messages);
// DBに保存...
}
...
配列だから、name.*のように、項目名に*が使用されていることに注意してください。
nullableは、空(null)の入力でもOKという意味です。
使用されるブレードは、
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">出費</div>
<div class="card-body">
<form method="POST" action="{{ route('form.store') }}">
@csrf
<div class="table-responsive">
<table class="table table-bordered table-hover table-sm">
<thead>
<tr>
<th class="">アイテム名</th>
<th class="">金額</th>
</tr>
</thead>
<tbody>
@for($i = 0; $i < 5; $i++)
<tr>
<td>
<input type="text" class="form-control @error('name.'.$i) is-invalid @enderror" name="name[]" value="{{ old('name.'.$i) }}">
@error('name.'.$i)
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</td>
<td>
<input type="text" class="form-control @error('price.'.$i) is-invalid @enderror" name="price[]" value="{{ old('price.'.$i) }}">
@error('price.'.$i)
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</td>
</tr>
@endfor
</tbody>
</table>
</div>
<div class="row justify-content-center">
<button type="submit" class="btn btn-primary">
保存
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@error('price.'.$i)と、price1でなくprice.1となっていることに注意してください。Laravelでは、price.1は指定の配列値で、price[1]と同じことです。同様に、old()でもold('price.'.$i)とprice.1となっています。
