如何在cakephp模型中使用countercache用于不同的别名?

时间:2014-07-10 02:20:43

标签: cakephp cakephp-2.3

我有以下模型:AttachmentPurchaseOrder因此数据广告attachmentspurchase_orders

PurchaseOrder,我有

class PurchaseOrder extends AppModel {
public $hasMany = array(
    'Pdf' => array(
        'className'  => 'Attachment',
        'foreignKey' => 'foreign_key',
        'conditions' => array(
            'Pdf.model' => 'PurchaseOrder'
        )
    ),
    'Zip' => array(
        'className'  => 'Attachment',
        'foreignKey' => 'foreign_key',
        'conditions' => array(
            'Zip.model' => 'PurchaseOrder'
        )
    ),

Attachment中,我有以下内容:

public $belongsTo = array(
    'PurchaseOrder' => array(
        'className' => 'PurchaseOrder',
        'foreignKey' => 'foreign_key',
        'counterCache' => array(
            'attachment_count' => array('Pdf.model' => 'PurchaseOrder'),
        )
    ),

我的问题是当我尝试使用$this->PurchaseOrder->Zip->save($data);时遇到问题,因为找不到别名Pdf

如何在保持更新attachment_count purchase_orders内的PurchaseOrder的反缓存行为的同时克服这个问题?

请注意,如果attachment_count与3个Pdf附件和2个Zip附件相关联,则{{1}}应为3。

我正在使用cakephp 2.4.2

2 个答案:

答案 0 :(得分:0)

我停止使用counterCache并改为使用afterSave

 /**
  * Called after each successful save operation.
  *
  * @param boolean $created True if this save created a new record
  * @param array $options Options passed from Model::save().
  * @return void
  * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#aftersave
  * @see Model::save()
  */
public function afterSave($created, $options = array()) {
    // update the PurchaseOrder based on pdf
    if (isset($this->data['Pdf'])) {
        $this->updatePurchaseOrderAttachmentCount($this->data);
    }
}

/**
 *
 * @param Array $data where we expect key Pdf
 */
public function updatePurchaseOrderAttachmentCount($data) {
    // check for Pdf
    $pdfSet = isset($data['Pdf']);
    if (!$pdfSet) {
        throw new Exception('we expect Pdf as a key in your $data');
    }
    // check for foreign_key and model
    $pdfFKSet = isset($data['Pdf']['foreign_key']);
    $pdfModelSet = isset($data['Pdf']['model']);
    if (!$pdfFKSet || !$pdfModelSet) {
        throw new Exception('we expect foreign_key and model as keys in your $data["Pdf"]');
    }
    $count = $this->find('count', array(
        'conditions' => array(
            'model' => 'PurchaseOrder',
            'type' => 'application/pdf',
            'foreign_key' => $data['Pdf']['foreign_key'],
        )
    ));
    if (!is_numeric($count)) {
        throw new Exception('we expect numeric in the $count');
    }
    $poData = array(
        'PurchaseOrder' => array(
            'id' => $data['Pdf']['foreign_key'],
            'attachment_count' => $count,
        )
    );
    return $this->PurchaseOrder->save($poData);
}

答案 1 :(得分:0)

我知道这篇文章很老,但我最近遇到了类似的问题,并找到了解决同一问题的另一种方法。您可以继续使用带有多个counterCache的counterCache方法,唯一的区别是,您需要在模型的__construct方法中动态添加关联。

public function __construct($id = false, $table = null, $ds = null) {
        parent::__construct($id, $table, $ds);

        /**
         * When using Aliases, associations need to be added on the fly, otherwise, the CounterScope conditions would result in an SQL Error, during counterCache updates
         */
        $this->bindModel(
                array('belongsTo' => array(
                        'PurchaseOrder' => array(
                            'className' => 'PurchaseOrder',
                            'foreignKey' => 'foreign_key',
                            'counterCache' => array(
                                 'attachment_count' => array($this->alias . '.model' => 'PurchaseOrder'),
                                 'attachment_count' => array($this->alias . '.model' => 'PurchaseOrder')
                            )
                        )
                    )
                )
        );
    }