CakePHP counterCache连接不相关的表以更新计数器



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

消息模型与用户模型链接两次,如下所示:

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'
    )
);

除了用户模型,消息模型也$belongs属于运营商模型。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

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

counterCache函数只是为了更新计数器而执行一个相当昂贵的查询。有没有一种方法可以覆盖或调整counterCache方法,使其不联接查询中不相关的表?

我现在无法测试它,但由于Model::updateCounterCache()使用的recursive设置是根据是否为计数器缓存字段定义了条件进行硬编码的,因此更改此设置的唯一方法(除了完全重新实现Model::updateCounterCache()之外(可能是修改Message模型的Model::_findCount()Model::beforeFind()中的count查询。

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,以防没有包含内容通过

$Message->contain(); // === recursive is being set to -1 in before find callback
$Message->delete(123);

最新更新