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

如何在Eloquent的with闭包$query中传递父表_user_id字段值

解决Laravel关联查询中with闭包内引用父模型字段的问题

我清楚你碰到的麻烦:在hasMany关联场景下,想在with方法的闭包查询里用上父表的_user_id字段值,但不知道怎么传递这个值到闭包中。咱们一步步拆解解决这个问题。

问题核心分析

先看你的关联定义,其实已经通过外键映射把父表的_user_id和关联表的user_id绑定了:

public function response_pricings(){
    return $this->hasMany('App\Models\Website\RFXRequestPricingResponse', ['rfx_request_id'=>'_rfx_request_id', 'user_id'=>'_user_id'])->selectRaw("*");
}

但你尝试在with闭包里直接写$query->where('user_id', $_user_id)时,闭包无法直接访问父模型的字段变量。这时候需要用Laravel关联查询的特性来处理父字段的引用。

可行解决方案

方案1:用whereColumn匹配关联字段

如果你的需求是确保关联的response_pricings数据的user_id和当前父模型的_user_id一致,其实这个约束已经在关联定义里自动生效了,不需要额外加where。但如果是要基于父字段做额外过滤,可以这样写:

->with(['response_pricings' => function ($query) {
    // 直接通过表字段关联,让关联表user_id匹配父表的_user_id
    $query->whereColumn('user_id', 'rfx_request_suppliers_responded._user_id');
    // 这里可以追加其他自定义条件,比如:
    // $query->where('status', 'active')->whereColumn('user_id', 'rfx_request_suppliers_responded._user_id');
}])

Laravel在关联查询时会自动处理表的关联关系,用表的原始字段名(父表名rfx_request_suppliers_responded+字段_user_id)就能正确匹配每个父模型对应的字段值。

方案2:针对单模型场景传递父值(批量查询不适用)

如果是单个父模型的查询场景,你可以通过use关键字把父模型的字段值引入闭包:

// 假设先获取单个父模型实例
$model = RFXRequestSupplierResponded::where('rfx_request_id', $rfx_request_id)->first();
$model->load(['response_pricings' => function ($query) use ($model) {
    $query->where('user_id', $model->_user_id);
}]);

但注意这种方式只适合单模型,批量查询(比如get()返回集合)时,use的是固定值,无法对应每个父模型的不同_user_id,所以优先用方案1。

代码优化建议

你主查询里用子查询获取user_name和note的写法,其实可以用Laravel的关联查询替代,让代码更简洁易维护:

// 先在RFXRequestSupplierResponded模型里定义关联
public function user() {
    return $this->belongsTo(User::class, 'user_id');
}

public function responseNote() {
    return $this->hasOne(RFXRequestResponseNote::class, ['rfx_request_id' => '_rfx_request_id', 'user_id' => '_user_id']);
}

// 然后重构查询代码
return RFXRequestSupplierResponded::select(
    'id as _id',
    'rfx_request_id as _rfx_request_id',
    'user_id as _user_id',
    'status',
    'is_qualified'
)
->with([
    'user:id,name', // 只加载需要的字段,提升性能
    'responseNote:rfx_request_id,user_id,note',
    'response_pricings'
])
->where('rfx_request_id', $rfx_request_id)
->get()
->map(function ($item) {
    // 把关联字段赋值成需要的别名
    $item->user_name = $item->user->name;
    $item->note = $item->responseNote?->note;
    return $item;
});

这种写法更符合Laravel的优雅风格,也方便后续维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:38:34