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

Laravel Eloquent关联查询:按Reservation的type筛选Jump数据

问题:Eloquent关联筛选无效的解决办法

原始查询代码

$cameras=Jump::Video()
    ->with('flight','flight.aircraft','flight.airfield')
    ->with('student','student.logininfo','student.logininfo.reservations')
    ->with('camera','camera.status')
    ->whereBetween('data',[ $from, $to])
    ->orderBy($sortBy, $orderDesc)
    ->paginate($request->perPage);

模型关联关系

Jump.php

public function scopeVideo($query)
{
    return $query->where('exercise', '104');
}

public function student() {
    return $this->hasOne('App\Models\PersonalData','id','student');
}

PersonalData.php

public function logininfo() {
    return $this->hasOne('App\User','id_user','id');
}

User.php

public function reservations() {
    return $this->hasMany('App\Models\Reservation','user_id', 'id');
}

需求与尝试的无效写法

需求:仅获取关联Reservation表中type字段等于$request->type的Jump数据。

尝试的两种无效写法:

  1. 直接查询关联字段(错误用法):
->where('student.logininfo.reservations','=',$request->type)
  1. 点语法的whereHas(未生效):
->whereHas('student.logininfo.reservations',function($query) use ($request) {
    return $query->where('type','=',$request->type)
})

解决办法

正确的筛选写法

写法一:嵌套whereHas(层级清晰,适合复杂关联)

$cameras=Jump::Video()
    ->with([
        'flight.aircraft', 'flight.airfield',
        'student.logininfo.reservations',
        'camera.status'
    ])
    ->whereBetween('data',[ $from, $to])
    ->whereHas('student', function ($query) use ($request) {
        $query->whereHas('logininfo', function ($query) use ($request) {
            $query->whereHas('reservations', function ($query) use ($request) {
                $query->where('type', $request->type);
            });
        });
    })
    ->orderBy($sortBy, $orderDesc)
    ->paginate($request->perPage);

写法二:点语法whereHas(简洁写法)

$cameras=Jump::Video()
    ->with([
        'flight.aircraft', 'flight.airfield',
        'student.logininfo.reservations',
        'camera.status'
    ])
    ->whereBetween('data',[ $from, $to])
    ->whereHas('student.logininfo.reservations', function($query) use ($request) {
        $query->where('type', $request->type);
    })
    ->orderBy($sortBy, $orderDesc)
    ->paginate($request->perPage);

无效原因排查

  1. 第一种写法完全错误:student.logininfo.reservations是Eloquent关联关系,不是数据库表字段,不能直接用where查询。
  2. 第二种写法本身语法正确,未生效可能是以下原因:
    • $request->type未传递有效值,可先通过dd($request->type)验证;
    • 模型关联的外键设置错误,比如PersonalData的logininfo关联中,id_user与id的对应关系是否和数据库字段匹配;
    • 数据链断裂:部分Jump没有关联的student,或student没有logininfo,或logininfo没有符合条件的reservations;
    • 闭包末尾遗漏分号(你提供的代码里确实少了分号)。

额外优化

将多个with()调用合并为一个数组参数,代码更简洁易读,如上述写法所示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 02:14:59