Laravel 无限级分类的简单实践

原文:https://segmentfault.com/a/119000001035909...(感谢作者给的思路和想法,但是按文章实践踩了不少坑,所以这边认真写个笔记对像我这样的萌新能友好一点)


目的:获取父id的全部后代(包括儿砸,孙砸...)

准备:

  • 一个数据表categories;
  • 一个category的model

实践:
1.创建模型文件,并用-m创建迁移文件

php artisan make:model Models/Category -m

2.修改database下的category迁移文件

Schema::create('categories', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('parent_id');
    $table->string('code');
    $table->string('name');
    $table->string('path');
    $table->timestamps();
});

3.运行迁移命令,生成数据表category

php artisan migrate

4.往表里随意填充测试数据,这边测试,就不用factory了

image

5.修改Category.php文件,增加下面俩方法

public function childCategory() {
    return $this->hasMany('App\Models\Category', 'parent_id', 'id');
}

public function allChildrenCategorys()
{
    return $this->childCategory()->with('allChildrenCategorys');
}

6.建立路由及控制器 测试

//无限极分类测试
public function index(){
    $category = Category::with('allChildrenCategorys')->find(5);
    $re = $category->allChildrenCategorys;

    dd($re);
}
//find一个parent_id = 0就可以

7.结果及解释
image
因为表里对于id=5的只有一个id=6的儿砸和id=7的孙砸

再次感谢大佬@sethhu的文章~

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 14

参考一下我的表结构吧。一个查询搞定所有子节点

file

5年前 评论
ShareMan 3年前
dwtmtdh 3年前
williamQian 2年前

参考一下我的表结构吧。一个查询搞定所有子节点

file

5年前 评论
ShareMan 3年前
dwtmtdh 3年前
williamQian 2年前

Laravel nestedset

Laravel 的无限级分类插件,分享一下

https://github.com/lazychaser/laravel-nest...

4年前 评论
野犭

在这基础之上可不可以思考下,如何获取集合中所有的子孙 id,并返回一个一维数组或集合,我这几天一直在思考如可用 laravel 自带的集合来处理,但是暂时还没有找到方法,想尽量避免手动递归

5年前 评论

我之前也是一直用的类似的方式来存放上下级数据,但是在层数变的非常大的时候(比如过万之后),首先表数据会很大,其次查询起来会很耗时甚至在读写数据的时候造成死锁。之前有个真实案例就是一个表行数达到了8000w行,虽然不是非常大,但是这种格式存放上下级关系在这种量级的数据下是很吃力的。当然,需求不一样代码就不一样,分享下个人经历给大家个参考吧~新年快乐!

4年前 评论
幽弥狂

@野犭 是根据子孙id 生成多维数组??还是一维数组?

5年前 评论

可以试试左右值无限级分类

5年前 评论

@野犭 我的做法是 categories 表添加两个字段 children_ids parent_ids 都是包含自身id的id数组,在栏目变化时直接更新相应父子栏目的数据,栏目多可以做缓存里

5年前 评论
Toiu

kalnoy/nestedset 这个包不错 左右值法.. 只是在经常更新层级关系的情况下略微有些耗资源

5年前 评论

:+1:

5年前 评论

如果我要查询所有的顶级分类下面所有的子分类。岂不是要用foreach。还有,这种查询的数据,不包含那个传入的ID

5年前 评论

没有写到模板渲染部分!还是看不懂

4年前 评论
public function menus()
{
    return $this->hasMany(self::class,'parent_id','id')
        ->select('id','category_name','parent_id')
        ->with(['menus']);
}
3年前 评论
模型文件
public function children() {
    return $this->hasMany(get_class($this), 'pid' ,'id');
}

public function allChildren() {
    return $this->children()->with( 'allChildren' );
}
    /**
     * 控制器分类列表
     * @param $data
     */
    public function categoryList($status, $name)
    {
        $list = $this->goodsCategory->where( function($query) use ($status) {
            if (!empty($status)) {
                $query->where('status', $status);
            }
        })->where(function($query) use ($name) {
            if (!empty($name)) {
                $query->where('name', 'LIKE', '%'.$name.'%');
            }
        })->with('allChildren')
        ->first();
        return $this->success($list);
    }
3年前 评论
Reason_bobo 3年前
PHPer技术栈 (作者) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!