Laravel数组必填验证失效问题求助
Laravel数组嵌套字段验证失效问题排查与解决
问题描述
在Laravel控制器的store方法中,对hospital_maintenance_details数组下的*.issues字段设置了required、array、min:1的验证规则,但即使不传递该数组或传递包含空issues数组的元素,验证仍不生效,代码可正常执行,无验证错误抛出。
原因分析
- 父数组未设置必填规则:
hospital_maintenance_details数组本身未添加required和array规则,导致当整个数组不传递时,Laravel直接跳过其内部所有字段的验证。 - 验证规则层级错误:原验证规则中,父数组的有效性规则(如是否必填、是否为数组)未与内部字段规则区分层级,父数组的合法性未被校验。
- Vue初始数据缺失字段:表单重置时,
machineryRows的初始对象未包含issues键,提交时部分元素可能缺失该字段,但因父数组未强制必填,验证规则未触发。 - 空数组绕过
required逻辑:Laravel的required规则仅检查字段是否存在,空数组属于“存在”的有效值,因此仅靠required无法拦截空数组,需结合min:1确保数组非空。
解决办法
1. 修正Laravel验证规则
给hospital_maintenance_details添加父级必填和数组规则,确保内部字段规则正确嵌套:
$attrs = $request->validate([ // 其他验证规则... 'hospital_maintenance_details' => [ 'required', 'array', 'min:1', // 父数组必须存在且为非空数组 '*.maintenance_master_id' => ['required', 'numeric'], '*.stock_SNW_id' => ['required', 'numeric'], '*.description' => ['nullable', 'string'], '*.issues' => ['required', 'array', 'min:1'], // 确保issues存在、是数组且至少有一个元素 '*.createdby' => ['required'], '*.updatedby' => ['required'], ], // 其他验证规则... ]);
2. 统一Vue初始数据结构
在表单重置时,给machineryRows的初始对象添加issues:[],避免提交时缺失字段:
machineryRows.value = [ { machinery_id:'', serial_no:'', tag_no:'', unit_id:'', mfg_date:'', exp_date:'', machine_status_id:'', project_id:'', qnt:'', price:'', total:0, description:'', issues:[] // 补充该字段,统一数据结构 }, ];
3. 可选:增强前端校验(提前拦截)
在Vue提交前,先校验每个machineryRow的issues数组是否非空,避免无效请求:
async function storeData() { clearErrorText(); // 前端提前校验 const hasEmptyIssues = machineryRows.value.some(row => row.issues.length === 0); if (hasEmptyIssues) { swal.fire({ title: 'Error!', text: '每个设备必须至少添加一个问题', icon: 'error', }); formProcessing.value = false; return; } formProcessing.value = true; // 后续提交逻辑... }
相关代码片段
Vue添加设备行函数
const addmachineryRow=()=>{ machineryRows.value.push({ stock_SNW_id:'', machinery_id:'', serial_no:'', tag_no:'', unit_id:'', mfg_date:'', exp_date:'', machine_status_id:'', project_id:'', qnt:'', price:'', total:0, description:'', issues:[] }); }
Vue添加问题函数
function addIssue(machineryRow) { machineryRow.issues.push({ stock_SNW_id:'', issue_solution:'', description: '' }); }
Laravel控制器store方法(修正后核心部分)
public function store(Request $request) { try { DB::beginTransaction(); $userID = auth()->user()->id; $request->request->add(['createdby' => $userID, 'updatedby' => $userID]); $attrs = $request->validate([ 'maintenance_reports' => [ 'hospital_id' => ['required'], 'year_id' => ['required'], 'month_id' => ['required'], 'assessment_date' => ['required', 'date_format:Y-m-d'], 'maktoob_no' => ['nullable'], 'maktoob_date' => ['required', 'date_format:Y-m-d'], 'status_id' => ['required'], 'remarks' => ['nullable'], 'description' => ['nullable'], 'createdby' => ['required'], 'updatedby' => ['required'], ], 'staff__performances' => [ 'required', 'array', 'min:1', '*.staff_id' => ['required'], '*.staff_role_id' => ['required'], '*.description' => ['nullable'], '*.createdby' => ['required'], '*.updatedby' => ['required'], ], 'hospital_maintenance_details' => [ 'required', 'array', 'min:1', '*.maintenance_master_id' => ['required', 'numeric'], '*.stock_SNW_id' => ['required', 'numeric'], '*.description' => ['nullable', 'string'], '*.issues' => ['required', 'array', 'min:1'], '*.createdby' => ['required'], '*.updatedby' => ['required'], ], // 其他验证规则... ]); // 后续业务逻辑... DB::commit(); return response()->json(['message' => 'Records added successfully']); }catch (\Exception $e) { DB::rollBack(); return response()->json(['message' => 'Error occurred: ' . $e->getMessage()], 500); } }
内容的提问来源于stack exchange,提问作者Newbie
相关产品推荐
相关产品推荐

