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
相关产品推荐
相关产品推荐

