Cakephp 3:在目标模型上具有条件的计数器缓存

时间:2018-12-18 12:49:49

标签: cakephp behavior cakephp-3.x counter-cache

我正在尝试计算与计划相关联的竞标数量,但仅限于在计划续订日期之后下载的竞标数量。希望有道理。我会像这样的图像,但是不起作用:

class SpotsTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('CounterCache', [
            'Plan' => [
                'creditsUsed' => [
                    'conditions' => [
                        'downloaded >' => 'Plan.renewed'
                    ]
                ]
            ]
        ]);
        ...
    }
...
}

基本上现在,它的行为就好像Plan.renewed意味着NULL一样。 这可能吗,还是我走错了路?

1 个答案:

答案 0 :(得分:0)

两个问题

1。标识符不能作为字符串值传递

使用key => value格式时,除非它是一个表达式对象,否则值侧将始终受绑定/转义/转换的约束,因此,由于downloaded列可能是日期/时间类型,因此您可以最终将Plan.renewed绑定为字符串,因此最终的SQL将类似于:

downloaded > 'Plan.renewed'

这可能总是导致错误。长话短说,例如使用标识符表达式:

'Spots.downloaded >' => new \Cake\Database\Expression\IdentifierExpression('Plan.renewed')

2。计数器查询无权访问关联的表

Plan.renewed在计数器缓存行为生成的查询中将不可访问,不会自动包含/加入关联,它将基于当前处理中的外键值创建一个条件简单的查询Spot实体。

因此,您必须使用自定义/修改后的查询,例如使用自定义查找器,例如:

'creditsUsed' => [
    'finder' => 'downloadedAfterPlanRenewal'
]
// in SpotsTable

public function findDownloadedAfterPlanRenewal(\Cake\ORM\Query $query, array $options)
{
    return $query
        ->innerJoinWith('Plan')
        ->where([
            'Spots.downloaded >' => $query->identifier('Plan.renewed')
        ]);
}

这将正确加入关联,以便您可以与Plan中的字段进行比较。由该行为生成的原始主键条件将已经应用于给定的查询对象。

另请参见