Laravel 8表单数组提交时days_id与hours_id多列联合唯一验证问题
解决方案
你现有代码的核心问题有两个:
- 原有
unique规则是单独验证days_id、hours_id全局唯一,并非两个字段的联合唯一校验 - 没有适配数组格式的提交参数,无法匹配每行的对应字段做校验
以下是可直接使用的实现代码:
1. 调整ScheduleRequest验证规则
首先引入Rule门面,然后遍历提交的数组项为每一行添加联合唯一校验:
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; class ScheduleRequest extends FormRequest { public function authorize() { return true; } public function rules() { $rules = [ 'teacher_classes_id' => 'required', 'days_id.*' => 'required', 'hours_id.*' => 'required', ]; // 逐行验证days_id和hours_id的组合是否已存在 foreach ($this->input('days_id', []) as $index => $dayId) { $rules["days_id.{$index}"] = Rule::unique('schedules', 'days_id') ->where('hours_id', $this->input("hours_id.{$index}")); } return $rules; } // 自定义错误提示,可定位到具体行 public function messages() { return [ 'days_id.*.required' => '第:position行的星期选项不能为空', 'hours_id.*.required' => '第:position行的课时选项不能为空', 'days_id.*.unique' => '第:position行的星期+课时组合已存在,请更换', ]; } }
2. 视图层显示对应行的错误提示
在每行的表单控件下方添加对应索引的错误提示即可:
<tr> <td class="day"> <input type="hidden" name="teasubid[]" value="{{ $teacher_subj->id }}"> <select name="days_id[]" class="form-control selectday"> @foreach ($days as $day) <option value="{{ $day->id }}"> {{ $day->name }} </option> @endforeach </select> {{-- 显示当前行的days_id错误 --}} @error("days_id.".$loop->index) <span class="text-danger small">{{ $message }}</span> @enderror </td> <td class="hour"> <select name="hours_id[]" class="form-control selecthour"> @foreach ($hours as $hour) <option value="{{ $hour->id }}"> {{ $hour->hours }} </option> @endforeach </select> {{-- 显示当前行的hours_id错误 --}} @error("hours_id.".$loop->index) <span class="text-danger small">{{ $message }}</span> @enderror </td> </tr>
编辑场景适配
如果是编辑已有排期的场景,需要排除当前编辑的记录,只需要在Rule::unique链式调用中添加ignore方法即可:
Rule::unique('schedules', 'days_id') ->where('hours_id', $this->input("hours_id.{$index}")) ->ignore($this->route('schedule')->id) // 根据你的路由参数名调整
内容的提问来源于stack exchange,提问作者Nawazaki
相关产品推荐
相关产品推荐

