gpt4 book ai didi

cakephp - 带有 Containable 条件的分页适用于 hasOne,但不适用于 hasMany

转载 作者:行者123 更新时间:2023-12-04 06:02:55 32 4
gpt4 key购买 nike

例如,我有这样的关系:

UserContact hasMany Contact
Contact hasOne Info
Contact hasMany Response

我需要对 Contact 进行分页,所以我使用 Containable:
$this->paginate = array(
'limit'=>50,
'page'=>$page,
'conditions' =>array('Contact.id'=>$id),
'contain'=>array(
'Response',
'Info'
)
);

我想通过 Info.name 和 Response.description 添加搜索。它适用于 信息名称 ,但如果我尝试使用 会引发错误Response.description ,表示该列不存在。

此外,我尝试将关系更改为 Contact hasOne Response,然后它正确过滤,但它只返回第一个响应,这不是正确的关系。

因此,例如,如果我有一个搜索键 $过滤器我只想返回那些具有匹配 的联系人信息名称 或至少一个匹配 Response.description .

最佳答案

如果您查看 CakePHP 如何构造 SQL 查询,您将看到它生成包含的“单个”关系( hasOnebelongsTo )作为主查询中的连接子句,然后它为包含的“多个”关系添加单独的查询.

这使得通过单个关系过滤变得轻而易举,因为相关模型的表已经加入了主查询。

为了按多重关系进行过滤,您必须创建一个子查询:

// in contacts_controller.php:
$conditionsSubQuery = array(
'Response.contact_id = Contact.id',
'Response.description LIKE' => '%'.$filter.'%'
);
$dbo = $this->Contact->getDataSource();
$subQuery = $dbo->buildStatement(array(
'fields' => array('Response.id'),
'table' => $dbo->fullTableName($this->Contact->Response),
'alias' => 'Response',
'conditions' => $conditionsSubQuery
), $this->Contact->Response);
$subQuery = ' EXISTS (' . $subQuery . ') ';

$records = $this->paginate(array(
'Contact.id' => $id,
$dbo->expression($subQuery)
));

但是如果您需要按 Response 过滤,您应该只生成子查询字段,否则您将过滤掉没有回复的联系人。

附注。这段代码太大太丑,无法在 Controller 中出现。对于我的项目,我将其重构为 app_model.php ,以便每个模型可以生成自己的子查询:
function makeSubQuery($wrap, $options) {
if (!is_array($options))
return trigger_error('$options is expected to be an array, instead it is:'.print_r($options, true), E_USER_WARNING);
if (!is_string($wrap) || strstr($wrap, '%s') === FALSE)
return trigger_error('$wrap is expected to be a string with a placeholder (%s) for the subquery. instead it is:'.print_r($wrap, true), E_USER_WARNING);

$ds = $this->getDataSource();

$subQuery_opts = array_merge(array(
'fields' => array($this->alias.'.'.$this->primaryKey),
'table' => $ds->fullTableName($this),
'alias' => $this->alias,
'conditions' => array(),
'order' => null,
'limit' => null,
'index' => null,
'group' => null
), $options);

$subQuery_stm = $ds->buildStatement($subQuery_opts, $this);
$subQuery = sprintf($wrap, $subQuery_stm);
$subQuery_expr = $ds->expression($subQuery);
return $subQuery_expr;
}

然后 Controller 中的代码变为:
$conditionsSubQuery = array(
'Response.contact_id = Contact.id',
'Response.description LIKE' => '%'.$filter.'%'
);
$records = $this->paginate(array(
'Contact.id' => $id,
$this->Contact->Response->makeSubQuery('EXISTS (%s)', array('conditions' => $conditionsSubQuery))
));

关于cakephp - 带有 Containable 条件的分页适用于 hasOne,但不适用于 hasMany,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8725867/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com