如何修改Laravel中belongsToMany()的返回数据格式?
问题:Laravel中belongsToMany关联如何合并pivot数据为指定格式
我在Laravel模型中使用belongsToMany()关联,当前关联方法代码如下:
public function platform_information(): BelongsToMany { return $this->belongsToMany( PlatformInformation::class, 'platform_information_artist', 'artist_id', 'platform_information_id')->withPivot([ 'date', 'value' ]); }
调用该方法获取数据时:
$artist->platform_information() ->orderBy('platform_information_id', 'asc') ->orderBy('date', 'asc') ->get()
返回的是包含重复平台信息、pivot字段单独存在的数据,但我需要将同一平台信息对应的pivot数据合并到data数组中,期望格式如下:
[ { "id": 1, "platform": "spotify", "information": "monthly_listeners", "data" : [ { "artist_id": 1, "platform_information_id": 1, "date": "2022-11-09", "value": 55400500 }, { "artist_id": 1, "platform_information_id": 1, "date": "2022-11-10", "value": 55395190 } ] }, { "id": 2, "platform": "spotify", "information": "followers", "data" : [ { "artist_id": 1, "platform_information_id": 2, "date": "2022-11-09", "value": 25390584 }, { "artist_id": 1, "platform_information_id": 2, "date": "2022-11-10", "value": 25410584 } ] } ]
请问能否直接通过belongsToMany()函数实现这种格式转换,还是必须在控制器中手动处理?
解答
不能直接通过belongsToMany()本身实现这种格式转换,因为该关联方法的核心是返回关联模型的集合,每条模型记录会附带自己对应的pivot数据,无法自动将同模型的pivot数据合并到一个数组中。不过你可以通过以下几种方式实现需求:
1. 利用Laravel集合方法在控制器中处理
获取数据后,使用集合的groupBy方法分组,再重新映射结构:
$platformInfos = $artist->platform_information() ->orderBy('platform_information_id', 'asc') ->orderBy('date', 'asc') ->get() ->groupBy('id') ->map(function ($items) { $info = $items->first()->toArray(); $info['data'] = $items->pluck('pivot')->toArray(); unset($info['pivot']); return $info; }) ->values();
2. 在模型中添加访问器或自定义方法
在Artist模型中定义一个自定义方法,封装上述逻辑,这样可以在多个地方复用:
public function getPlatformInformationWithDataAttribute() { return $this->platform_information() ->orderBy('platform_information_id', 'asc') ->orderBy('date', 'asc') ->get() ->groupBy('id') ->map(function ($items) { $info = $items->first()->toArray(); $info['data'] = $items->pluck('pivot')->toArray(); unset($info['pivot']); return $info; }) ->values(); }
使用时直接调用:
$artist->platform_information_with_data;
3. 自定义关联查询(进阶)
如果不想返回集合后处理,可以直接通过SQL查询构造器拼接数据,比如使用GROUP_CONCAT(适用于MySQL)将pivot数据拼接成JSON,再在模型中解析,但这种方式对数据库有依赖,灵活性较低,不如集合处理直观。
内容的提问来源于stack exchange,提问作者Luis Alberto Murcia Solivella
相关产品推荐
相关产品推荐

