查询生成器 when() 方法产生条件错误的查询
Posted
技术标签:
【中文标题】查询生成器 when() 方法产生条件错误的查询【英文标题】:Query builder when() method producing wrongly conditioned query 【发布时间】:2021-12-13 17:43:47 【问题描述】:我发布了我认为是 Laravel 错误 (https://github.com/laravel/framework/issues/39398) 但它已关闭,因为我不是 100% 认为它确实是一个错误。其他人能否告诉我这种行为是否错误?
我有以下代码:
$user=251;
$description='created';
Activity::when($user, function ($query, $user)
return $query->where('causer_id', $user)
->orWhere(function($query) use ($user)
$query->where('subject_id', $user)
->where('subject_type', "App\\User");
);
)->when($description, function ($query, $description)
return $query->where('description', $description);
);
从逻辑上讲,我认为它应该生成一个查询,该查询返回具有正确用户和正确描述的所有行,但无论描述如何,我都会获得该用户的所有行。
上面的代码产生了这个 sql 查询:
select * from activity_log where causer_id = '251' or (subject_id = '251' and subject_type = 'App\User') and description = 'created'
...而我认为它应该产生:
select * from activity_log where (causer_id = '251' or (subject_id = '251' and subject_type = 'App\User')) and (description = 'created')
简而言之:when() 函数不应该在返回的结果周围加上括号以不影响查询的其他部分吗?它不是一个错误吗?
【问题讨论】:
【参考方案1】:我不认为这是一个错误。这不是被破坏的预期行为。这将是添加到框架中的一项新功能。您可以访问 discord 服务器并尝试提出您的理由,或者只是提交一个 PR 并进行更改并为之辩护,但这并不是“破坏”现有功能。
when()
方法只是语法糖,因此您可以有条件地修改方法链中的查询,而无需分解为单独的 if
语句。下面的代码是等价的:
$query = Activity::query();
if ($user)
$query->where('causer_id', $user)
->orWhere(function($query) use ($user)
$query->where('subject_id', $user)
->where('subject_type', "App\\User");
);
if ($description)
$query->where('description', $description);
正如您在上面的代码中看到的那样,不希望有条件添加的任何子句都包含在括号中(除非在您的 orWhere()
调用中明确指定)。
您所期望的一个问题是when()
方法可用于以任何方式修改查询,而不仅仅是添加额外的条件。那么,如果您在 when()
子句中添加了 orderBy()
或 limit()
,您期望会发生什么?
因此,when()
方法本身不会修改您的查询,但它会完全按照您的指示运行。因此,要执行您要查找的内容,您需要自己将查询包装在 when()
子句中:
Activity::when($user, function ($query, $user)
return $query->where(function($query) use ($user)
return $query->where('causer_id', $user)
->orWhere(function($query) use ($user)
$query->where('subject_id', $user)
->where('subject_type', "App\\User");
);
);
)
->when($description, function ($query, $description)
return $query->where('description', $description);
);
【讨论】:
好的。看完你说的,我意识到我错了。当然 when() 不应该影响查询。但有一件事是,这在文档中可能会更清楚。但我现在停止抱怨:-)以上是关于查询生成器 when() 方法产生条件错误的查询的主要内容,如果未能解决你的问题,请参考以下文章