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

Laravel Eloquent模型:如何让查询方法返回关联贡献者数据?

解决方案

完全不需要放弃Eloquent,用Laravel自带的关联模型和自动加载就能实现你的需求,步骤如下:

1. 定义模型关联

首先在Book模型中定义与Author的多对多关联,通过中间表contribution关联,同时指定要获取中间表的role字段:

// app/Models/Book.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Book extends Model
{
    // 定义与作者的多对多关联
    public function contributors(): BelongsToMany
    {
        return $this->belongsToMany(Author::class, 'contribution', 'book_id', 'contributor_id')
            ->withPivot('role'); // 取出中间表的role字段
    }
}

2. 自动加载关联

如果你希望每次查询Book时自动带上贡献者数据,只需在Book模型中添加$with属性,这样all()、find()、get()等方法返回的结果都会自动包含contributors:

// app/Models/Book.php
class Book extends Model
{
    // ... 其他代码

    protected $with = ['contributors']; // 自动加载关联
}

3. 调整返回格式(可选)

默认情况下,关联返回的contributors会包含pivot对象存储role,如果想让role和id、name同级,可以在Book模型中定义访问器重写contributors属性:

// app/Models/Book.php
class Book extends Model
{
    // ... 其他代码

    public function getContributorsAttribute()
    {
        return $this->contributors->map(function ($author) {
            return [
                'id' => $author->id,
                'name' => $author->name,
                'role' => $author->pivot->role
            ];
        });
    }
}

效果验证

现在执行Book::find(1)->toArray(),返回的结构就和你期望的一致:

[
    "id" => "1",
    "title" => "CS101",
    "contributors" => [
        [
            "id" => "1",
            "name" => "Einstein",
            "role" => "author"
        ],
        [
            "id" => "2",
            "name" => "Thomas",
            "role" => "translator"
        ]
    ]
]

这种方式完全遵循Eloquent的设计理念,不需要重写核心方法,既优雅又易于维护。

内容的提问来源于stack exchange,提问作者Đức Thành Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:37:24