如何使用Laravel Eloquent实现主分类(cat_head)与子分类的分组查询?
嘿,这个需求其实挺常见的,用Laravel的Eloquent配合集合方法就能轻松实现,我给你详细说下步骤:
1. 先确认你的模型定义
假设你的表名是categories,先创建对应的Category模型(如果还没建的话):
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Category extends Model { // 替换成你的实际表名 protected $table = 'categories'; // 允许批量赋值的字段 protected $fillable = ['category_name', 'cat_head']; }
2. 核心查询实现
要实现按cat_head分组,把对应的category_name作为子分类,有几种实用方式:
方式一:基础分组(直接返回分组后的集合)
在控制器里直接查询并分组,这种方式保留完整的模型数据,适合需要额外处理子分类字段的场景:
use App\Models\Category; // 只查询需要的字段,优化数据库性能 $groupedCategories = Category::select('cat_head', 'category_name') ->get() ->groupBy('cat_head');
返回的$groupedCategories是Laravel集合,键为cat_head的值,对应值是该分组下的所有分类模型集合。
方式二:格式化子分类为名称数组
如果只需要子分类的名称列表,不需要完整模型,可以用map和pluck简化结果:
$formattedCategories = Category::select('cat_head', 'category_name') ->get() ->groupBy('cat_head') ->map(function ($subCategories) { // 提取子分类名称并转成数组 return $subCategories->pluck('category_name')->toArray(); });
最终输出的结构会是这样:
[ "suit" => ["ultra slim suit", "slim suit"], "shoes" => ["Shoes"], "accessories" => ["Hats", "Cufflinks"] ]
方式三:封装成模型方法(提升复用性)
如果这个分组逻辑需要在多个页面使用,可以把它封装成模型的静态方法:
// 在Category模型中添加 public static function getGroupedMenu() { return self::select('cat_head', 'category_name') ->get() ->groupBy('cat_head') ->map(fn($group) => $group->pluck('category_name')->toArray()); }
之后在控制器里直接调用即可:
$categories = Category::getGroupedMenu();
3. 在视图中渲染菜单
用Blade模板的话,可以这样遍历渲染主菜单和子分类:
@foreach($formattedCategories as $mainMenu => $subCategories) <div class="menu-section"> <h4>{{ ucfirst($mainMenu) }}</h4> <!-- 首字母大写优化显示效果 --> <ul class="sub-menu"> @foreach($subCategories as $subCategory) <li>{{ $subCategory }}</li> @endforeach </ul> </div> @endforeach
这样就能完美实现你要的「cat_head作为主菜单,category_name作为子分类」的嵌套结构啦!
内容的提问来源于stack exchange,提问作者Gaurav Jadhav
相关产品推荐
相关产品推荐

