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

Laravel中基于ID数组关联purchases与purchase_types表的实现

问题分析

你的代码返回空数组的核心原因是:purchases表的purchaseCategory字段存储的是JSON格式的ID数组,而你用普通的等值join和whereIn是在拿数组字符串和单个ID数值做匹配,两者不可能相等,因此无法命中任何数据。

解决方案

根据Laravel的特性,我们可以利用JSON查询语法来处理这类数组字段,以下提供两种实现方式:

方式一:使用Query Builder(无模型)

1. 查询符合条件的采购记录

先筛选出purchaseCategory包含指定ID的采购数据:

$purchaseIds = [1, 2];

$purchases = DB::table('purchases')
    ->where(function ($query) use ($purchaseIds) {
        // 遍历目标ID,用orWhereJsonContains匹配数组中包含任意目标ID的记录
        foreach ($purchaseIds as $id) {
            $query->orWhereJsonContains('purchaseCategory', $id);
        }
    })
    ->get();

2. 批量获取对应的采购类型

为了避免N+1查询,先收集所有涉及的类型ID,再一次性查询:

// 提取所有采购记录中的类型ID,去重
$allTypeIds = collect($purchases)
    ->pluck('purchaseCategory')
    ->flatten()
    ->unique();

// 批量查询类型名称,用ID作为键名方便后续匹配
$purchaseTypes = DB::table('purchase_types')
    ->whereIn('id', $allTypeIds)
    ->pluck('purchaseType', 'id');

方式二:使用Eloquent模型(推荐)

如果已经定义了模型,我们可以用访问器简化类型名称的获取:

1. 定义模型与访问器

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

use Illuminate\Database\Eloquent\Model;

class Purchase extends Model
{
    protected $casts = [
        'purchaseCategory' => 'array', // 自动将JSON字段转为数组
    ];

    // 定义访问器,直接返回对应的采购类型名称字符串
    public function getPurchaseTypeNamesAttribute()
    {
        return PurchaseType::whereIn('id', $this->purchaseCategory)
            ->pluck('purchaseType')
            ->implode(', ');
    }
}
// app/Models/PurchaseType.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class PurchaseType extends Model
{
    // 模型默认配置即可
}

2. 控制器查询

$purchaseIds = [1, 2];

$purchases = Purchase::where(function ($query) use ($purchaseIds) {
    foreach ($purchaseIds as $id) {
        $query->orWhereJsonContains('purchaseCategory', $id);
    }
})->get();
Blade模板显示

对应Query Builder方式的显示

@foreach($purchases as $purchase)
    <div class="purchase-item">
        <h4>采购ID: {{ $purchase->id }}</h4>
        <p>采购类型:
            @foreach($purchase->purchaseCategory as $typeId)
                {{ $purchaseTypes[$typeId] }}@if(!$loop->last), @endif
            @endforeach
        </p>
    </div>
@endforeach

对应Eloquent模型方式的显示

直接调用访问器即可,无需额外处理:

@foreach($purchases as $purchase)
    <div class="purchase-item">
        <h4>采购ID: {{ $purchase->id }}</h4>
        <p>采购类型: {{ $purchase->purchase_type_names }}</p>
    </div>
@endforeach

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:10:34