You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中hasMany关联子项更新时的唯一性验证问题

Laravel更新父模型时验证子项Code唯一性(忽略自身ID)

方案一:自定义闭包验证

直接通过闭包解析当前子项ID,排除自身后检查Code唯一性:

$parent = Parent::find($id);

$rules = [
    'code' => ['required', Rule::unique('parents', 'code')->ignore($parent->id)],
    'childrens.*.code' => [
        'required',
        function ($attribute, $value, $fail) use ($parent) {
            // 拆分属性名获取子项索引,比如 "childrens.2.code" 拆出索引2
            $index = explode('.', $attribute)[1];
            // 获取当前子项的ID(新增子项时该值为null)
            $childId = request()->input("childrens.$index.id");
            
            // 构建查询:检查code是否存在,排除自身ID
            $query = \App\Models\Children::where('code', $value);
            if ($childId) {
                $query->where('id', '!=', $childId);
            }
            // 若业务要求子项Code仅在所属父模型下唯一,取消下面注释
            // $query->where('parent_id', $parent->id);
            
            if ($query->exists()) {
                $fail('该子项编码已存在');
            }
        }
    ],
];

方案二:动态使用Rule::unique的ignore方法

利用Laravel内置规则,通过闭包动态获取当前子项ID并忽略:

use Illuminate\Validation\Rule;

$parent = Parent::find($id);

$rules = [
    'code' => ['required', Rule::unique('parents', 'code')->ignore($parent->id)],
    'childrens.*.code' => [
        'required',
        Rule::unique('childrens', 'code')
            ->ignore(function ($value, $attribute) {
                $index = explode('.', $attribute)[1];
                // 新增子项时无ID,ignore(0)不影响(数据库ID通常从1开始)
                return request()->input("childrens.$index.id") ?? 0;
            })
            // 若需父模型内唯一,添加下面的where条件
            // ->where('parent_id', $parent->id)
    ],
];

注意事项

  • 更新子项时,请求的childrens数组必须包含已有子项的id字段,新增子项可省略id。
  • 如果业务规则是子项Code仅在所属父模型下唯一,务必添加where('parent_id', $parent->id)条件,避免跨父模型的Code冲突。

内容的提问来源于stack exchange,提问作者GAOUL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:05:20