Cakephp 3:在目标模型上使用条件进行反缓存

Cakephp 3: Countercache with conditions on the target model

我正在尝试计算与计划关联的点数,但仅限于计划续订日期之后下载的点数。希望这是有道理的。我会想象这样的事情,但它不起作用:

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

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

两个问题

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

当使用 key => value 格式时,值端将始终遵循 binding/escaping/casting 除非它是表达式对象,因此由于 downloaded 列可能是 date/time 类型,你最终会得到 Plan.renewed 被绑定为一个字符串,因此最终的 SQL 将类似于:

downloaded > 'Plan.renewed'

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

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

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

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

因此您必须使用 custom/modified 查询,例如使用自定义查找器,如下所示:

'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 中的字段进行比较。行为生成的原始主键条件将已应用于给定的查询对象。

另见