Laravel where 条件位于“with”内

问题描述 投票:0回答:2

我有一个雄辩的疑问:

        $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);

以及学生、登录信息和预订之间的关系

模型跳转.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');
    }

模型用户.php

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

我只想获得表“预订”(模型预订)中“类型”等于 $request->type

的跳转

我正在尝试:

->where('student.logininfo.reservations','=',$request->type)

->whereHas('student.logininfo.reservations',function($query) use ($request) {
    return $query->where('type','=',$request->type)
})

但没有成功。有什么建议吗?

php laravel where-clause eloquent-relationship
2个回答
1
投票

有两件事,您不需要多个

->with()
子句,也不需要多次链接同一个表。您可以将
->with()->with()->with()
简化为:

->with(['flight.aircraft', 'flight.airfield', 'student.logininfo.reservations' , 'camera.status'])

student.logininfo.reservations
这样的点符号会加载
students,
logininfo
reservations
关系,所以你不需要
->with('a', 'a.b', 'a.b.c')
,只需要
->with('a.b.c')

接下来,如果您只想加载特定类型的

reservations
,您可以将一个函数附加到您的
with()

->with(['student.logininfo.reservations' => function ($query) use ($request) {
  return $query->where('reservations.type', $request->type);
}]);

如果您需要将

Jump
模型限制为仅具有特定
reservations.type
的模型,请使用
->whereHas()
:

->whereHas('student.logininfo.reservations', function ($query) use ($request) {
  return $query->where('reservations.type', $request->type);
});

如果您需要过滤和限制,那么您使用

->withWhereHas()

->withWhereHas('student.logininfo.reservations', function ($query) use ($request) {
  return $query->where('reservations.type', $request->type);
});

所以,把它们放在一起:

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

根据需要进行调整,如果遇到困难,请参考文档:

https://laravel.com/docs/11.x/eloquent-relationships#querying-relations

https://laravel.com/docs/11.x/eloquent-relationships#querying-relationship-existence


0
投票

谢谢你的帖子。这真的很有帮助。不幸的是 withWhereHas 正在杀死我的服务器。我不知道为什么,但服务器没有响应(连接超时)。看起来像是超载了。我什至无法停止聆听(php artisanserve),我需要终止 php(laravel)进程。

我使用了 Flight、flight.aircraft 等,因为它是对这种情况的简化,并且在我的实际代码中,我使用特定字段来限制下载对象的大小。我的真实代码如下所示:

        $cameras=Jump::Video()
        ->with('flight:id,nr,data,data_zalozenia,godz_ladowania,samolot,miejsce',
            'flight.aircraft:id,typ,znaki',
            'flight.airfield:id,icao,miejscowosc')
        ->with('ins1:id,imie,nazwisko,ilosc_skokow','ins1.logininfo:id,id_user,email,avatar,role')
        ->with('skydiver:id,imie,nazwisko,ilosc_skokow,waga','skydiver.logininfo:id,id_user,username,email,avatar,role')
        ->with('student:id,imie,nazwisko,ilosc_skokow,waga','student.logininfo:id,id_user,username,email,avatar,role','student.logininfo.reservations')
        ->with('camera','camera.status','camera.editor:id,imie,nazwisko','camera.editor.logininfo:id,id_user,email,avatar,role')
        ->whereBetween('data',[ $from, $to])
        ->orderBy($sortBy, $orderDesc)
        ->paginate($request->perPage);

我将此代码更改为:

        $cameras=Jump::Video()
        ->with('flight:id,nr,data,data_zalozenia,godz_ladowania,samolot,miejsce',
            'flight.aircraft:id,typ,znaki',
            'flight.airfield:id,icao,miejscowosc')
        ->with('ins1:id,imie,nazwisko,ilosc_skokow','ins1.logininfo:id,id_user,email,avatar,role')
        ->with('skydiver:id,imie,nazwisko,ilosc_skokow,waga','skydiver.logininfo:id,id_user,username,email,avatar,role')
        ->with('student:id,imie,nazwisko,ilosc_skokow,waga','student.logininfo:id,id_user,username,email,avatar,role')
        ->withWhereHas('student.logininfo.reservations', function ($query) use ($request) {
            return $query->where('rezerwacja.kamera', $request->type);})
        ->with('camera','camera.status','camera.editor:id,imie,nazwisko','camera.editor.logininfo:id,id_user,email,avatar,role')
        ->whereBetween('data',[ $from, $to])
        ->orderBy($sortBy, $orderDesc)
        ->paginate($request->perPage);

我的服务器(laravel)不再响应:(我必须终止 php 进程并重新启动服务器才能使其恢复正常。

© www.soinside.com 2019 - 2024. All rights reserved.