Laravel多对多关联:按Color字段排序获取Fabrics并分页
解决方案
你之前的写法存在两个核心问题:
- 用
with闭包排序仅会给每个Fabric关联的Color集合内部排序,不会改变Fabric本身的整体排序顺序 - 直接使用
join(默认是内连接)会过滤掉无关联颜色的Fabric,同时代码里存在拼写错误(acs应为asc,color.name应为colors.name)
要实现「按Color的name升序排序,无关联颜色的Fabric排在最后」的需求,需要通过左连接+自定义排序规则+去重来实现,具体代码如下:
return Fabrics::leftJoin('fabrics_colors', 'fabrics.id', '=', 'fabrics_colors.fabric_id') ->leftJoin('colors', 'colors.id', '=', 'fabrics_colors.color_id') ->select('fabrics.*') ->orderByRaw('colors.name IS NULL, colors.name ASC') ->distinct() ->with('colors') ->paginate($pageSize);
代码说明:
- 左连接(leftJoin):分别关联中间表
fabrics_colors和颜色表colors,确保无关联颜色的Fabric不会被过滤 - select('fabrics.*'):仅查询Fabric表的字段,避免多表连接后出现字段冲突
- orderByRaw:
colors.name IS NULL会返回布尔值,有颜色的Fabric此值为false(数据库中对应0),无颜色的为true(对应1),因此有颜色的Fabric会优先排在前面- 在此基础上,再按
colors.name ASC对有颜色的Fabric按颜色名称升序排序
- distinct():由于一个Fabric可能关联多个Color,左连接后会生成多条重复的Fabric记录,用
distinct去重保证每个Fabric只出现一次 - with('colors'):预加载Color关联,避免后续访问Fabric的颜色时产生N+1查询
内容的提问来源于stack exchange,提问作者Aziz Ismailov
相关产品推荐
相关产品推荐

