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

Laravel 10中如何获取各客户的最新tgl_pengajuan数据?

Laravel 10 获取客户最新tgl_pengajuan问题

目标需求

我使用Laravel 10开发项目,需要在PenawaranController.php中获取每个客户的最新tgl_pengajuan,期望得到如下格式的结果:

customer_id | name  | email           | latest_penawaran_by_cust
----------------------------------------------------------------
1           | david | david@gmail.com | 2023-12-20 01:00:00
2           | alan  | alan1@gmail.com | null

当前问题

执行dd($penawaran[0]->customer);后,得到的数据结构不符合预期,出现了嵌套重复的Customer模型:

App\Models\Customer {
  #connection: "mysql"
  #table: "customers"
  .. // 其他属性
  #attributes: array:9 [
    "id" => 1
    "name" => "david"
    "email" => "david@gmail.com"
    .. // 其他字段
    "latestPenawaranByCust" => Illuminate\Database\Eloquent\Collection {
      "items: array:1 {
        0 => App\Models\Customer {
          #connection: "mysql"
          #table: "customers"
          .. // 其他属性
          #attributes: array:8 [
            "id" => 1
            "name" => "david"
            "email" => "david@gmail.com"
            .. // 其余和上面一致,但无lastPenawaranByCust

表结构(简化版)

  • customers表:
id | name  | email
--------------------------------
1  | david | david@gmail.com
2  | alan  | alan1@gmail.com
  • barangs表:
id | name           | stok | harga
-----------------------------------
1  | laptop 14 inch | 100  | 150
2  | USB cable      | 50   | 10
  • penawarans表:
id | customer_id | tgl_pengajuan       | updated_at
----------------------------------------------------
1  | 1           | 2023-12-19 00:00:00 | 2023-12-15 05:00:00
2  | 1           | 2023-12-20 01:00:00 | 2023-12-17 07:00:00
  • detail_penawaran表:
id | penawaran_id | barang_id | qty | harga
--------------------------------------------
1  | 1            | 1         | 11  | 200
2  | 1            | 2         | 22  | 20
3  | 2            | 1         | 12  | 210

现有代码

模型文件

Models/Penawaran.php

public function detail_penawaran()
{
    return $this->belongsToMany(DetailPenawaran::class);
}

public function customer()
{
    return $this->belongsTo(Customer::class);
}

Models/DetailPenawaran.php

public function penawaran()
{
    return $this->hasOne(Penawaran::class);
}

public function barang()
{
    return $this->hasMany(Barang::class);
}

Models/Customer.php

public function penawarans()
{
    return $this->hasMany(Penawaran::class, 'customer_id');
}

public function latestPenawaranByCust()
{
    return $this->hasOne(Penawaran::class, 'customer_id')->latest('updated_at');
}

控制器文件 PenawaranController.php

$penawaran = Penawaran::where('id', '=', $id)->get();

if ($penawaran) {
    $tglPenawaranByCust = Customer::where('id', '=', $penawaran[0]->customer->id)
        ->with(['latestPenawaranByCust' => function($query) {
            $query->whereNotNull('updated_at');
        }])
        ->orderBy('nama', 'ASC')
        ->get();
    $penawaran[0]['customer']['latestPenawaranByCust'] = $tglPenawaranByCust;
}
dd($penawaran[0]->customer);

解决方案

1. 修正模型关联错误

DetailPenawaran的关联逻辑有误,需调整为:

// Models/DetailPenawaran.php
public function penawaran()
{
    return $this->belongsTo(Penawaran::class);
}

public function barang()
{
    return $this->belongsTo(Barang::class);
}

Penawaran与DetailPenawaran的关联应为一对多:

// Models/Penawaran.php
public function detail_penawaran()
{
    return $this->hasMany(DetailPenawaran::class);
}

2. 修正关联排序字段

要获取最新的tgl_pengajuan,需按该字段排序,而非updated_at:

// Models/Customer.php
public function latestPenawaranByCust()
{
    return $this->hasOne(Penawaran::class, 'customer_id')->latest('tgl_pengajuan');
}

3. 简化控制器逻辑

无需单独查询Customer再赋值,直接通过预加载获取关联数据:

// PenawaranController.php
// 按id查询单条报价,用first()替代get()
$penawaran = Penawaran::with(['customer.latestPenawaranByCust'])
    ->where('id', $id)
    ->first();

// 如果需要获取所有客户的最新报价,直接查询Customer并格式化输出
$customersWithLatestPenawaran = Customer::with(['latestPenawaranByCust'])
    ->select('id', 'name', 'email')
    ->orderBy('name', 'ASC')
    ->get()
    ->map(function ($customer) {
        return [
            'customer_id' => $customer->id,
            'name' => $customer->name,
            'email' => $customer->email,
            'latest_penawaran_by_cust' => $customer->latestPenawaranByCust?->tgl_pengajuan
        ];
    });

dd($customersWithLatestPenawaran);

问题根源说明

之前的控制器代码中,$tglPenawaranByCust = Customer::...->get()返回的是Customer集合,将其赋值给latestPenawaranByCust导致嵌套了Customer模型。正确做法是直接预加载latestPenawaranByCust关联(它是Penawaran模型),再取出其中的tgl_pengajuan字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:54:58