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

Laravel 如何编写子查询实现 Receipts 关联 Ingradients 表返回嵌套结构数据

Laravel 嵌套结构查询实现方案

1. 定义模型关联

首先在对应模型中配置一对多关联关系:

Receipt 模型

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

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

class Receipt extends Model
{
    // 非默认表名需手动指定
    protected $table = 'Receipts';

    // 定义和食材表的一对多关联
    public function ingradients(): HasMany
    {
        // 参数依次为:关联模型、外键名、当前模型主键名
        return $this->hasMany(Ingradient::class, 'id_receipt', 'id');
    }
}

Ingradient 模型

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

use Illuminate\Database\Eloquent\Model;

class Ingradient extends Model
{
    protected $table = 'Ingradients';
    // 表无created_at/updated_at字段时需关闭自动时间戳
    public $timestamps = false;
}

2. 执行关联查询

使用 Laravel 预加载方法with查询即可自动生成嵌套结构:

// 查询所有菜谱及对应食材
$receipts = Receipt::with('ingradients')->get();

// 查询单个id为5的菜谱及对应食材
$receipt = Receipt::with('ingradients')->find(5);

// 直接返回即可得到要求的JSON格式
return $receipts;

3. 可选优化:指定查询字段

如果不需要表中全部字段,可通过闭包筛选返回字段,减少数据传输:

$receipts = Receipt::select('id', 'name', 'advice')
    ->with([
        'ingradients' => function($query) {
            // 关联查询必须包含外键id_receipt,否则关联无法匹配
            $query->select('id_ingradient', 'id_receipt', 'ingradient', 'type_measuring');
        }
    ])
    ->get();

注意事项

  • 预加载with方法可避免N+1查询问题,性能远高于循环查询子数据
  • 自定义外键必须在关联方法中显式指定,否则Laravel会默认使用receipt_id作为外键导致关联失败
  • 关联子查询中必须包含关联外键id_receipt,否则无法正确匹配父子数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:45:09