在网上商城上,咱们常常能够看到多级分类、子分类、甚至无限极分类。本文将向你展现如何优雅的经过 Laravel Eloquent 将其实现。php
咱们会建立一个微型项目来展现儿童商店的分类,总共有 5 级,以下:node
数据库迁移web
简单的数据表结构:数据库
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->unsignedBigInteger('category_id')->nullable();
$table->foreign('category_id')->references('id')->on('categories');
$table->timestamps();
});
只有一个 name 字段, 关联到其自身。因此,大部分父级分类 category_id = NULL,每个子分类都有一个 parent_id架构
数据表数据以下:app
Eloquent 模型和关联关系学习
首先,在 app/Category.php 建立一个简单的 hasMany() 方法, 分类可能拥有其自分类:this
class Category extends Model { public function categories() { return $this->hasMany(Category::class); } }
好戏开场 本文最妙 “计策”。你知道能够向这样描述 递归 关系吗?以下:spa
public function childrenCategories() { return $this->hasMany(Category::class)->with('categories'); }
所以,若是调用 Category::with(‘categories’),将获得下级 “子分类”,可是经过 Category::with(‘childrenCategories’) 将能帮你实现无限极。code
路由和控制器方法
如今,让咱们尝试显示全部类别和子类别,如上例所示。
在 routes/web.php,咱们添加如下内容:
Route::get('categories', 'CategoryController@index');
app/Http/CategoryController.php 以下所示:
public function index() { $categories = Category::whereNull('category_id') ->with('childrenCategories') ->get(); return view('categories', compact('categories')); }
咱们仅加载父类别,将子类别做为关系。简单吧?
视图和递归子视图
最后,渲染到页面。 在 resources/views/categories.blade.php 文件:
<ul> @foreach ($categories as $category) <li>{{ $category->name }}</li> <ul> @foreach ($category->childrenCategories as $childCategory) @include('child_category', ['child_category' => $childCategory]) @endforeach </ul> @endforeach </ul>
咱们先遍历了最顶级的父类别,而后遍历出父类的子类别,而后使用 @include 加载子类别的子类别......
最好的部分是 resources/views/admin/child_category.blade.php 将使用递归加载自身。看代码:
<li>{{ $child_category->name }}</li> @if ($child_category->categories) <ul> @foreach ($child_category->categories as $childCategory) @include('child_category', ['child_category' => $childCategory]) @endforeach </ul> @endif
在 child_category.blade.php 内部,咱们包含了 @include(‘child_category’),所以只要当前子类别中有类别,模板就会递归地加载子类别。
就是这样!咱们拥有无限级别的子类别 - 不管是在数据库仍是关联关系或是视图中
更多学习内容请访问: