Laravel 5.4 - WhereHas

时间:2017-04-24 21:34:45

标签: laravel where laravel-5.4

我们有一个用Laravel 5.2编写的旧应用程序。我们目前正在尝试升级到5.4,而我们最后一件事就是在哪里有一个bug。 以下是原始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之间的差异。 OR子句在5.4

中生成

知道为什么吗?

1 个答案:

答案 0 :(得分:3)

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

  

Eloquent范围现在尊重范围约束的主要布尔值。例如,如果您使用orWhere约束启动范围,则将不再将其转换为normal。如果您依赖于此功能(例如,在循环中添加多个或者约束),则应验证第一个条件是否正常,以避免任何布尔逻辑问题。

在5.2中,如果你的第一个条件是orWhere(),那么它会忽略' OR'部分和' AND'它与其他条件。从5.3开始,它尊重“OR”。部分和意志'或者'其余条件的第一个条件。

如果您需要' AND',则需要将第一个条件从orWhere()更改为where()

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