Laravel 5.4 - 哪里有

Laravel 5.4 - whereHas

我们有一个用 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子句

知道为什么吗?

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

Eloquent scopes now respect the leading boolean of scope constraints. For example, if you are starting your scope with an orWhere constraint it will no longer be converted to normal where. If you were relying on this feature (e.g. adding multiple orWhere constraints within a loop), you should verify that the first condition is a normal where to avoid any boolean logic issues.

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

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

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