You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:45:14