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

Laravel7下如何在单filters表中保存多级分组及关联parent_id等字段

问题1:checkbox_name、color_name、color_code字段为空的解决方案
  • 首先确认Filter模型已开启对应字段的批量赋值权限,修改app/Models/Filter.php的$fillable属性:
protected $fillable = [
    'category_id', 'parent_id', 'name', 'latin', 'field',
    'checkbox_name', 'color_name', 'color_code'
];
  • 修正原有store方法的赋值逻辑,原有代码未将三个字段加入存储数组,同时修复updateOrCreate的查询条件错误(原有$request[0]为无效参数):
public function store(Request $request)
{
    $filters = collect([]);
    if ($request->filters) {
        foreach ($request->filters as $filter) {
            if ($filter['name'] != null && $filter['field'] != null) {
                $model = Filter::updateOrCreate(
                    // 编辑场景下每个filter需带隐藏id字段,新增时id为空自动创建新数据
                    ['id' => $filter['id'] ?? null],
                    [
                        'name' => $filter['name'],
                        'latin' => $filter['latin'],
                        'field' => $filter['field'],
                        'category_id' => $request->category_id,
                        'parent_id' => 0,
                        // 新增三个字段的赋值
                        'checkbox_name' => $filter['checkbox_name'] ?? null,
                        'color_name' => $filter['color_name'] ?? null,
                        'color_code' => $filter['color_code'] ?? null,
                    ]
                );
                $filters->push($model);
            }
        }
    }
    Filter::whereNotIn('id', $filters->pluck('id'))->delete();
    return redirect()->back();
}
  • 如果是编辑场景,需在JS动态生成字段时增加id隐藏项:
'<input type="hidden" name="filters['+count+'][id]" value="'+ 编辑态对应filter的id + '">'+
问题2:子组parent_id关联主组的实现方案

前端修改

调整动态表单结构,区分主组和子组层级,给每个主组增加「添加子组」按钮,按层级命名表单字段,示例JS逻辑:

let groupCount = 0;
// 生成主组字段
function addGroup() {
    let groupHtml = `<div class="filter-group mb-3 p-3 border">
        <input type="hidden" name="groups[${groupCount}][id]" value="">
        <input type="text" class="form-control mb-2" name="groups[${groupCount}][name]" placeholder="主组名称">
        <!-- 其他主组字段和原有一致 -->
        <a class="add-child-btn btn btn-sm btn-secondary mt-2" data-group-index="${groupCount}">添加子组</a>
        <div class="child-container mt-2 ms-4"></div>
    </div>`;
    $('#showFilters').append(groupHtml);
    groupCount++;
}

// 点击添加子组按钮生成对应主组下的子组字段
$('body').on('click', '.add-child-btn', function() {
    let groupIndex = $(this).data('group-index');
    let childCount = $(this).next('.child-container').find('.child-item').length;
    let childHtml = `<div class="child-item mb-2 p-2 border">
        <input type="hidden" name="groups[${groupIndex}][children][${childCount}][id]" value="">
        <input type="text" class="form-control mb-1" name="groups[${groupCount}][children][${childCount}][name]" placeholder="子组名称">
        <!-- 其他子组字段和主组一致 -->
    </div>`;
    $(this).next('.child-container').append(childHtml);
})

后端存储逻辑修改

调整store方法,先存储主组获取主组ID,再遍历存储对应子组,将子组的parent_id赋值为对应主组的ID:

public function store(Request $request)
{
    $existIds = collect([]);
    if ($request->groups) {
        foreach ($request->groups as $group) {
            // 先存储主组
            $parentFilter = Filter::updateOrCreate(
                ['id' => $group['id'] ?? null],
                [
                    'category_id' => $request->category_id,
                    'parent_id' => 0,
                    'name' => $group['name'],
                    'latin' => $group['latin'] ?? null,
                    'field' => $group['field'] ?? null,
                    'checkbox_name' => $group['checkbox_name'] ?? null,
                    'color_name' => $group['color_name'] ?? null,
                    'color_code' => $group['color_code'] ?? null,
                ]
            );
            $existIds->push($parentFilter->id);

            // 存储该主组下的所有子组
            if (isset($group['children']) && count($group['children']) > 0) {
                foreach ($group['children'] as $child) {
                    $childFilter = Filter::updateOrCreate(
                        ['id' => $child['id'] ?? null],
                        [
                            'category_id' => $request->category_id,
                            'parent_id' => $parentFilter->id, // 关联对应主组ID
                            'name' => $child['name'],
                            'latin' => $child['latin'] ?? null,
                            'field' => $child['field'] ?? null,
                            'checkbox_name' => $child['checkbox_name'] ?? null,
                            'color_name' => $child['color_name'] ?? null,
                            'color_code' => $child['color_code'] ?? null,
                        ]
                    );
                    $existIds->push($childFilter->id);
                }
            }
        }
    }
    // 删除当前分类下未提交的旧数据
    Filter::where('category_id', $request->category_id)->whereNotIn('id', $existIds)->delete();
    return redirect()->back();
}

无限级子组扩展

如果需要支持超过两级的无限级子组,只需要将后端存储逻辑改为递归处理层级结构即可,逻辑和两级存储一致,每次存储完父节点后遍历子节点赋值parent_id。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:27:06