Laravel急切加载和whereHas

6

这个问题已经被问了很多次,但都没有提供一个令人满意的解释。

我运行以下查询:

$return = Vacation::whereHas('dates', function ($query) use ($from, $to) {
    $query->whereBetween('start_date', [$from, $to]);
})->get();

根据查询日志,这会产生以下SQL语句。返回结果是正确的,但是JOIN后的数据存在问题。
select * from `vacations` where exists (select * from `vacation_dates` where `vacations`.`id` = `vacation_dates`.`vacation_id` and `start_date` between '2017-08-01 00:00:00' and '2017-08-30 00:00:00')

由于没有JOIN操作,相关记录通过急切加载后添加,约束条件丢失。

场景涉及具有多个开始/停止日期的“假期”,我想检查哪些“假期”的start_date$start$end日期范围内。

如果没有匹配项,则不返回任何记录。

当出现匹配项时,将返回整个“假期”记录而不仅仅是符合约束条件的记录。

我明白它正在做什么,但不知道如何得到我需要的结果:符合约束条件的连接数据记录。

有人能帮忙吗?


你尝试过使用 whereRaw() 吗? - Leo
是的,似乎也不能做我想要的事情。 - stef
2个回答

9

5

和@stef给出的答案相同,但语法更好看(我认为)


$return = Vacation::query()
    ->whereHas('dates', $datesFilter = function($query) use ($from, $to) {
        $query->whereBetween('start_date', [$from, $to]);
    })
    ->with(['dates' => $datesFilter])
    ->get();

“query()”是用来做什么的? - Robby Alvian Jaya Mulia
@RobbyAlvianJayaMulia 这是显式地启动 (db) 查询的语法。它会返回 Eloquent\Builder 类的实例,因此您可以自动完成更多方法。 当您使用 Vacation::whereHas() 时,它会隐式地返回相同的 Builder 类。 - Yerke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接