Laravel中如何在关联关系内使用orderBy进行排序?
问题描述
我知道这可能是个基础问题,但我无法通过关联关系解决它。
我的模型代码:
public function category(): BelongsTo { return $this->belongsTo('App\Models\Master\Product\Category'); }
控制器代码如下:
$products = Product::with('category')->orderBy('category.name')->get();
但我遇到了Unknown error column 'category.name'的错误,尽管该字段确实存在。我知道可以通过左连接解决,代码如下:
$products= Product::leftJoin('categories', 'categories.id','products.category_id')->orderBy('categories.name')->get();
但我想知道如何仅通过关联关系来使用orderBy实现排序?
解决方案
核心原因
with()只是预加载关联数据,不会将关联表引入主查询的FROM/JOIN子句,所以直接用orderBy('category.name')会报错——主查询里根本没引用category表。
方式一:关联约束+隐式关联排序(推荐)
既预加载关联数据,又按关联字段对主表排序,无需手动写完整join:
$products = Product::with(['category' => function ($query) { // 可选:同时对预加载的分类数据自身排序 $query->orderBy('name'); }]) ->join('categories', 'products.category_id', '=', 'categories.id') ->orderBy('categories.name') ->select('products.*') // 避免主表与关联表字段冲突 ->get();
方式二:子查询排序
用子查询直接获取关联字段值用于排序,完全依赖关联逻辑:
$products = Product::with('category') ->orderByRaw('(SELECT name FROM categories WHERE categories.id = products.category_id)') ->get();
方式三:全局关联排序(仅对关联数据生效)
如果所有场景下预加载的分类都需要按名称排序,可以在关联定义中加入全局排序:
public function category(): BelongsTo { return $this->belongsTo('App\Models\Master\Product\Category')->orderBy('name'); }
注意:这种方式只会调整预加载的分类数据顺序,不会改变主表Product的排序。
内容的提问来源于stack exchange,提问作者Efendy zheng
相关产品推荐
相关产品推荐

