Laravel如何在Scope中按关联模型排序?
按关联Country模型名称排序的实现方法
嗨,作为Laravel新手,这个需求其实很好解决~我们可以用两种常用方法来实现按关联国家名称排序的需求,下面给你详细说明:
方法一:使用表关联(Join)
这种方式性能更优,适合数据量较大的场景,通过将users表和countries表关联起来,直接按国家表的name字段排序:
$query->with('country') ->when($filters['search'] ?? null, function ($query, $search) { return $query->where('name', 'LIKE', '%' . $search . '%') ->orWhereHas('country', function ($query) use ($search) { $query->where('name', 'LIKE', '%' . $search . '%'); }); }) // 关联countries表,通过user的country_id匹配国家id ->join('countries', 'users.country_id', '=', 'countries.id') // 按国家名称升序排序 ->orderBy('countries.name', 'asc') // 只选择users表的所有字段,避免两个表的name字段冲突 ->select('users.*');
注意事项:
- 如果你的
Country模型使用了SoftDeletes软删除特性,需要在关联时加上软删除的过滤条件:
->join('countries', function ($join) { $join->on('users.country_id', '=', 'countries.id') ->whereNull('countries.deleted_at'); })
- 确保
countries是你的国家表实际表名,如果模型里自定义了表名,要改成对应的值。
方法二:使用子查询排序(无需Join)
如果你不想通过关联表的方式,也可以用子查询直接获取对应国家的名称来排序,写法更简洁:
$query->with('country') ->when($filters['search'] ?? null, function ($query, $search) { return $query->where('name', 'LIKE', '%' . $search . '%') ->orWhereHas('country', function ($query) use ($search) { $query->where('name', 'LIKE', '%' . $search . '%'); }); }) // 通过子查询获取当前用户对应的国家名称,再排序 ->orderByRaw('(SELECT name FROM countries WHERE countries.id = users.country_id) asc');
这种写法不需要关联整个表,适合小型数据集,不过性能上相比Join会稍差一些,根据你的实际场景选择即可。
内容的提问来源于stack exchange,提问作者Rickin Rathatha
相关产品推荐
相关产品推荐

