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

Laravel/Lumen Eloquent多模型关联:关联三张表返回完整数据

我来帮你搞定这个Laravel/Lumen Eloquent多表关联查询的问题!下面一步步拆解实现方案:

解决Laravel/Lumen多模型关联查询问题

首先咱们先理清楚三张表的关联逻辑:

  • 一个客户对应多个网站(customers → customer_websites 是一对多关系)
  • 一个网站对应一个状态(customer_websites → customer_websites_status 通常是一对一,若需历史状态可调整为一对多)

第一步:定义模型关联

先把三个模型的关联关系配置好,确保外键匹配你的数据库字段:

Customer 模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{
    protected $table = 'customers';

    // 关联客户名下的所有网站
    public function websites()
    {
        return $this->hasMany(CustomerWebsite::class, 'customer_id');
    }
}

CustomerWebsite 模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class CustomerWebsite extends Model
{
    protected $table = 'customer_websites';

    // 关联所属客户
    public function customer()
    {
        return $this->belongsTo(Customer::class, 'customer_id');
    }

    // 关联网站的状态(一对一,若需最新历史状态可加->latest())
    public function status()
    {
        return $this->hasOne(CustomerWebsiteStatus::class, 'website_id');
        // 若需取最新状态:return $this->hasOne(CustomerWebsiteStatus::class, 'website_id')->latest();
    }
}

CustomerWebsiteStatus 模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class CustomerWebsiteStatus extends Model
{
    protected $table = 'customer_websites_status';

    // 关联所属网站
    public function website()
    {
        return $this->belongsTo(CustomerWebsite::class, 'website_id');
    }
}

第二步:控制器查询并格式化返回

在控制器中使用**预加载(Eager Loading)**避免N+1查询问题,同时把数据格式化成你需要的结构:

namespace App\Http\Controllers;

use App\Models\Customer;
use Illuminate\Http\Response;

class CustomerController extends Controller
{
    public function show($customerId)
    {
        // 预加载客户的网站,以及每个网站对应的状态
        $customer = Customer::with(['websites.status'])->findOrFail($customerId);

        // 按需求格式化返回数据(可根据你的字段调整)
        $formattedResponse = [
            'customer_info' => [
                'id' => $customer->id,
                'name' => $customer->name,
                'email' => $customer->email,
                // 其他客户字段...
            ],
            'websites' => $customer->websites->map(function ($website) {
                return [
                    'website_id' => $website->id,
                    'url' => $website->url,
                    'domain' => $website->domain,
                    // 其他网站字段...
                    'status' => $website->status ? [
                        'status_id' => $website->status->id,
                        'status_code' => $website->status->status_code,
                        'status_desc' => $website->status->description,
                        'updated_at' => $website->status->updated_at
                        // 其他状态字段...
                    ] => null // 处理网站无状态的情况
                ];
            })
        ];

        return response()->json($formattedResponse, Response::HTTP_OK);
    }
}

额外优化提示

  • 如果需要筛选特定状态的网站,可在预加载时添加条件:
    $customer = Customer::with([
        'websites' => function ($query) {
            $query->where('is_active', true); // 只加载活跃网站
        },
        'websites.status'
    ])->findOrFail($customerId);
    
  • 若customer_websites_status是历史状态表(一个网站有多个状态),可将CustomerWebsite的status关联改为hasMany,再在格式化时取最新一条或全部状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:10:04