我想从父类别中删除所有相关的子类别。我想我需要一个递归函数来解决这个问题。这是我的尝试:
public function destroy(Request $request)
{
$categories = AppCategories::select('parent_id')->whereNotNull('parent_id')->get();
foreach ($categories as $category) {
if ($category->parent_id == $request->cid) {
$childCategories = AppCategories::select('parent_id')->where('parent_id', $category->parent_id)->get();
}
}
}
我的桌子是这样的
+-------------+----------+-----------+
| id | name | parent_id |
+-------------+----------+-----------+
| 1 | MAIN | NULL |
+-------------+----------+-----------+
| 2 | CHILD | 1 |
+-------------+----------+-----------+
| 3 | CHILD 2 | 2 |
+-------------+----------+-----------+
我的期望:
如果我删除了主要类别,则必须删除子类别和子类别 2。
我怎样才能雄辩地做到这一点?
答案还可以,但它没有像我预期的那样工作。我想删除所有子类别及其派生物。给出的示例仅查找第一个节点。
溶液
我通过迁移解决了这个问题。
我为PARENT_ID创建了一个外键,它引用了迁移文件中类别的 ID。当我执行删除操作时,它会使用子节点删除自身(如果它的子节点具有子节点,它也可以工作(。
这是我使用的迁移代码:
$table->foreign('parent_id'(->references('id'(->on('categories'(->onDelete('cascade'(; 然后
App\Categories::find($id(->delete((; 已删除子节点。
您还需要检查子类别的子条目。你会有更深入的数据吗?
如果你重复更好
foreach ($categories as $category) {
内部也带有子类别,以查找内部是否存在子类别。
我通过迁移解决了这个问题。
我为PARENT_ID创建了一个外键,它引用了迁移文件中类别的 ID。当我执行删除操作时,它会使用子节点删除自身(如果它的子节点具有子节点,它也可以工作(。
这是我使用的迁移代码:
$table->foreign('parent_id')->references('id')->on('categories')->onDelete('cascade');
然后
AppCategories::find($id)->delete();
使用子节点删除。
我遇到了同样的问题,2~3 小时后我想出了这个对我有用的递归解决方案。
if (!function_exists('CategoryTree')) {
function CategoryTree($categories = []) {
$categories = (new Category())->whereIn('parent_id', $categories)->get()->toArray();
if(count($categories) > 0){
return array_merge($categories, deleteCategoryTree(array_column($categories, 'id')));
}
return $categories;
}
}
当你不得不称这个$categories = CategoryTree([1]);
.此函数将为您提供一个数组,其中包含从参数中作为数组传递的 id(s( 派生的所有类别。
要删除这些记录,您可以使用以下内容。
(new Category())->whereIn('id', array_column($categories, 'id'))->delete();