【发布时间】:2021-03-09 15:51:31
【问题描述】:
我正在编写支持基于 CakePHP 3 的 API 的自定义查询构建器代码。我最近收到一个请求,要求它针对关联用户的任务项进行搜索。
从任务到用户的关联是belongsToMany,到目前为止,自定义查询功能还不支持。 TasksTable.php 中的关系如下所示:
<?php
$this->belongsToMany('Users', [
'foreignKey' => 'task_id',
'targetForeignKey' => 'user_id',
'through' => 'TasksUsers'
]);
查询构建器使用 Cake\Database\Expression\QueryExpression 来执行查询,因为它必须处理比我用 Cake\Database\Query 能够处理的更复杂的查询。但是我现在正在尝试嵌套一个 QueryExpression 来处理在这个 belongsToMany 关系上查询用户。
代码非常抽象。为了简单起见,我将 TasksTable 上的 Search\Model\Filter\Base 实现简化为下面的代码。这正好说明了我在运行它时正在处理的问题。
<?php
public function process(): bool
{
$this->getQuery()->where(function (QueryExpression $exp, Query $query) {
return $query->newExpr()->eq('Users.id', 621048);
})->contains('Users');
}
上面给了我:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Users' in 'where clause'"
我想知道如何修改 where 子句中嵌套函数的返回值和 contains 的内容,以完成对用户的 belongsToMany 关系的连接?
附带说明,我知道示例查询可以使用matching() 方法针对查询执行,如here 所示。但是,这不适用于我的解决方案,因为必须使用 QueryExpressions 检查自定义搜索中的所有内容以与查询生成器的其余部分兼容。
提前感谢您的意见!
【问题讨论】:
-
使用
matching()(你最好使用innerJoinWith()以避免选择列表被操纵)与使用查询表达式有什么关系?没有什么可以强迫您使用表达式与列进行简单的相等比较。 -
谢谢 我不知道matching()。用于动态生成从软件其他部分的配置加载的查询的自定义查询构建器。它允许和/或操作的深度嵌套。我不知道没有表达方式可以做到这一点。我只是想知道使用关联加入 belongsToMany 的正确方法是什么。我很乐意根据需要改写问题。
-
正则数组样式的比较在添加到查询时会被转换为表达式,因此最终您通常会得到类似的表达式树。您也可以在连接查询构建器中使用表达式,就像在您的示例 sn-p 中一样。话虽如此,我不明白为什么您需要任何特殊操作才能在此处使用
matching()或*joinWith(),只需在您的查询中调用它即可。 -
不管其他的,你肯定想比较
'Users.id',而不是'Users'? -
@GregSchmidt 是的,我更正了。谢谢!
标签: php mysql cakephp associations cakephp-4.x