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

Laravel 8 Eloquent rightJoin如何将关联表数据封装为独立属性

Laravel 8 Eloquent 嵌套返回关联表数据解决方案

Laravel Eloquent 原生提供了关联预加载功能,可以直接实现你要的嵌套结构,不需要手动重构数据,也是官方推荐的最佳实践。


方案1:使用关联预加载(推荐)

步骤1:定义模型关联

首先在Book模型中定义和关联表(你示例中的tableB,对应阅读进度表)的关联关系,你当前的业务场景下是一对一关联:

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

    // 定义和阅读进度表的关联
    public function tableB()
    {
        return $this->hasOne(TableB::class, 'book_id', 'id');
    }
}

注意将TableB替换为你实际的关联表对应的模型类名。

步骤2:执行关联查询

使用whereHas过滤出对应用户有阅读进度的书籍,再用with方法预加载关联数据:

return Book::whereHas('tableB', function ($query) use ($uid) {
        $query->where('user_id', $uid);
    })
    ->with('tableB')
    ->get();

执行后返回的结构完全符合你的预期,每个书籍对象下会自动挂载tableB属性,属性值就是关联表的所有字段组成的对象。


方案2:如果你坚持使用JOIN语句

如果因为特殊需求必须手动写JOIN,可以用数据库JSON函数来封装关联字段,需要依赖数据库的JSON支持(MySQL 5.7+ 都支持):

  1. 先在Book模型的$casts属性中添加字段类型转换:
// App/Models/Book.php
protected $casts = [
    'tableB' => 'object', // 或 'array' 根据你的需要选择
];
  1. 写查询语句:
return Book::rightJoin('tableB', 'tableB.book_id', '=', 'book.id')
    ->where('tableB.user_id', $uid)
    ->select(
        'book.*',
        \DB::raw('JSON_OBJECT("col1", tableB.col1, "col2", tableB.col2) as tableB')
    )
    ->get();

该方案需要手动指定关联表的所有字段,维护成本更高,不推荐常规场景使用。


内容的提问来源于stack exchange,提问作者Bytech

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:39:02