【问题标题】:Laravel 5.4 - whereHasLaravel 5.4 - whereHas
【发布时间】:2017-09-21 17:24:42
【问题描述】:

我们有一个用 Laravel 5.2 编写的旧应用程序。我们目前正在尝试升级到 5.4,最后阻碍我们的是 whereHas 错误。 以下是原始 sql 查询:

# Laravel 5.4 Query:
select * from `jobs` where exists (select * from `channels` where `jobs`.`channel_id` = `channels`.`id` OR (`id` = 'RetroSnickers' or `channelid` like 'RetroSnickers' or `channelname` like 'RetroSnickers' or exists (select * from `users` where `channels`.`user_id` = `users`.`id` and (`email` like 'RetroSnickers' or `full_name` like 'RetroSnickers')))) and `jobs`.`deleted_at` is null limit 24 offset 0

# Laravel 5.2 Query:
select * from `jobs` where exists (select * from `channels` where `jobs`.`channel_id` = `channels`.`id` AND (`id` = 'RetroSnickers' or `channelid` like 'RetroSnickers' or `channelname` like 'RetroSnickers' or exists (select * from `users` where `channels`.`user_id` = `users`.`id` and (`email` like 'RetroSnickers' or `full_name` like 'RetroSnickers')))) and `jobs`.`deleted_at` is null limit 24 offset 0

这是生成此原始 sql 的代码。我们的 5.4 版本的代码和 5.2 版本的代码是一样的:

$this->query->whereHas('channel', function(Builder $query) use ($search) {

            $query->orWhere('id', '=', $search);
            $query->orWhere('channelid', 'like', '%'.$search.'%');
            $query->orWhere('channelname', 'like', '%'.$search.'%');

            $query->orWhereHas('user', function(Builder $subQuery) use ($search) {

                $subQuery->where(function(Builder $subQuery2) use ($search) {

                    $subQuery2->orWhere('email', 'like', '%'.$search.'%');
                    $subQuery2->orWhere('full_name', 'like', '%'.$search.'%');
                });
            });
        });

原始 sql 的唯一区别是粗体,但基本上是 mysql OR 与 AND 之间的区别。 5.4 中生成 OR 子句

知道为什么吗?

【问题讨论】:

  • 您可以尝试将第一个orWhere(... 更改为where(... 吗?
  • 是的,做到了。这是5.4的变化吗?我刚刚开始 xdebugging 整个事情,但我不认为我会抓住这个。如果你回答正确,我会给你积分/积分。

标签: laravel where laravel-5.4


【解决方案1】:

这是 Laravel 5.3 中发生的变化。来自5.3 upgrade guide

Eloquent 作用域现在尊重作用域约束的前导布尔值。例如,如果您从 orWhere 约束开始您的范围,它将不再转换为正常的 where。如果您依赖此功能(例如,在循环中添加多个 orWhere 约束),您应该验证第一个条件是正常的 where 以避免任何布尔逻辑问题。

在 5.2 中,如果您的第一个 where 条件是 orWhere(),它将忽略“OR”部分并与其余条件“AND”。从 5.3 开始,它尊重“或”部分,并将“或”第一个条件与其余条件。

如果您期待“与”,则需要将第一个条件从 orWhere() 更改为 where()

$query->where('id', '=', $search);

【讨论】:

    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 2021-08-23
    • 1970-01-01
    • 2019-12-28
    • 2023-03-07
    • 2017-06-09
    相关资源
    最近更新 更多