CakePHP counterCache加入不相关的表来更新计数器

时间:2014-08-01 07:26:50

标签: mysql cakephp

我有一个用户模型和一个消息模型。

Message模型两次链接到User模型:

public $belongsTo = array(
    'UserSender' => array(
        'className' => 'User',
        'foreignKey' => 'sender_id',
        'counterCache' => array(
            'messages_sent_count' => array(
                'is_deleted' => FALSE
            )
        )
    ),
    'UserRecipient' => array(
        'className' => 'User',
        'foreignKey' => 'recipient_id',
        'counterCache' => array(
            'messages_received_count' => array(
                'is_deleted' => FALSE
            ),
            'messages_unread_count' => array(
                'is_deleted' => FALSE,
                'is_read' => FALSE
            )
        )
    ),
    'Operator' => array(
        'className' => 'Operator',
        'foreignKey' => 'operator_id'
    )
);

除了User模型之外,Message模型还$属于Operator模型。运算符模型与用户的消息计数无关,但其表仍在计数查询中加入,如调试所示:

'query' => 'SELECT COUNT(*) AS `count` FROM `database`.`messages` AS  `Message` LEFT JOIN `database`.`operators` AS `Operator` ON (`Message`.`operator_id` = `Operator`.`id`) LEFT JOIN `database`.`users` AS `UserSender` ON (`Message`.`sender_id` = `UserSender`.`id`) LEFT JOIN `database`.`users` AS `UserRecipient` ON (`Message`.`recipient_id` = `UserRecipient`.`id`)  WHERE `Message`.`is_deleted` = '0' AND `Message`.`sender_id` = 389',
        'params' => array(),
        'affected' => (int) 1,
        'numRows' => (int) 1,
        'took' => (float) 394

为了简单起见,我实际上排除了另一个消息模型$ belongsTo的模型,但上面的查询显示了问题。

counterCache函数只是为了更新计数器而进行非常昂贵的查询。有没有办法可以覆盖或调整counterCache方法,以便不在查询中连接不相关的表?

1 个答案:

答案 0 :(得分:3)

我现在无法对其进行测试,但由于the recursive setting used by Model::updateCounterCache()是基于是否为计数器缓存字段定义条件而进行硬编码的,因此唯一可以改变此方法(除了完全重新实现{{1} }}}可能会修改Model::updateCounterCache()模型的countModel::_findCount()中的Model::beforeFind()查询。

Message

根据您实际需要的控制程度,containable行为也可能起作用,如果没有传递包含,它会将public function beforeFind($query) { // ... figure whether this is the count query for updateCounterCache, // maybe even try to analyze whether the passed conditions require // joins or not. if(/* ... */) { $query['recursive'] = -1; } return $query; } 设置为recursive

-1