Skip to content

Commit fb7fbcf

Browse files
committed
Added option to disable counter caches updating.
Closes #3109
1 parent 8ff5958 commit fb7fbcf

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

lib/Cake/Model/Model.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,8 @@ public function field($name, $conditions = null, $order = null) {
15751575
* @param mixed $value Value of the field
15761576
* @param boolean|array $validate Either a boolean, or an array.
15771577
* If a boolean, indicates whether or not to validate before saving.
1578-
* If an array, allows control of 'validate' and 'callbacks' options.
1578+
* If an array, allows control of 'validate', 'callbacks' and 'counterCache' options.
1579+
* See Model::save() for details of each options.
15791580
* @return boolean See Model::save()
15801581
* @see Model::save()
15811582
* @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savefield-string-fieldname-string-fieldvalue-validate-false
@@ -1598,13 +1599,20 @@ public function saveField($name, $value, $validate = false) {
15981599
* @param array $data Data to save.
15991600
* @param boolean|array $validate Either a boolean, or an array.
16001601
* If a boolean, indicates whether or not to validate before saving.
1601-
* If an array, allows control of validate, callbacks, and fieldList
1602+
* If an array, it can have one of the following options:
1603+
* - validate: Boolean as mentioned above
1604+
* - fieldList: See $fieldList parameter
1605+
* - callbacks: Controls callbacks triggering. Valid values: true, false, 'before', 'after'
1606+
* - counterCache: Boolean to control updating of counter caches (if any)
16021607
* @param array $fieldList List of fields to allow to be written
16031608
* @return mixed On success Model::$data if its not empty or true, false on failure
16041609
* @link http://book.cakephp.org/2.0/en/models/saving-your-data.html
16051610
*/
16061611
public function save($data = null, $validate = true, $fieldList = array()) {
1607-
$defaults = array('validate' => true, 'fieldList' => array(), 'callbacks' => true);
1612+
$defaults = array(
1613+
'validate' => true, 'fieldList' => array(),
1614+
'callbacks' => true, 'counterCache' => true
1615+
);
16081616
$_whitelist = $this->whitelist;
16091617
$fields = array();
16101618

@@ -1738,7 +1746,7 @@ public function save($data = null, $validate = true, $fieldList = array()) {
17381746
}
17391747
}
17401748

1741-
if ($success && !empty($this->belongsTo)) {
1749+
if ($success && $options['counterCache'] && !empty($this->belongsTo)) {
17421750
$this->updateCounterCache($cache, $created);
17431751
}
17441752
}
@@ -2019,7 +2027,9 @@ protected function _prepareUpdateFields($data) {
20192027
* 'AssociatedModel' => array('field', 'otherfield')
20202028
* )
20212029
* }}}
2022-
* - deep: see saveMany/saveAssociated
2030+
* - deep: See saveMany/saveAssociated
2031+
* - callbacks: See Model::save()
2032+
* - counterCache: See Model::save()
20232033
*
20242034
* @param array $data Record data to save. This can be either a numerically-indexed array (for saving multiple
20252035
* records of the same type), or an array indexed by association name.
@@ -2055,6 +2065,8 @@ public function saveAll($data = array(), $options = array()) {
20552065
* Should be set to false if database/table does not support transactions.
20562066
* - fieldList: Equivalent to the $fieldList parameter in Model::save()
20572067
* - deep: If set to true, all associated data will be saved as well.
2068+
* - callbacks: See Model::save()
2069+
* - counterCache: See Model::save()
20582070
*
20592071
* @param array $data Record data to save. This should be a numerically-indexed array
20602072
* @param array $options Options to use when saving record data, See $options above.
@@ -2155,9 +2167,9 @@ public function validateMany(&$data, $options = array()) {
21552167
*
21562168
* #### Options
21572169
*
2158-
* - `validate` Set to `false` to disable validation, `true` to validate each record before saving,
2170+
* - validate: Set to `false` to disable validation, `true` to validate each record before saving,
21592171
* 'first' to validate *all* records before any are saved(default),
2160-
* - `atomic` If true (default), will attempt to save all records in a single transaction.
2172+
* - atomic: If true (default), will attempt to save all records in a single transaction.
21612173
* Should be set to false if database/table does not support transactions.
21622174
* - fieldList: Equivalent to the $fieldList parameter in Model::save().
21632175
* It should be an associate array with model name as key and array of fields as value. Eg.
@@ -2168,6 +2180,8 @@ public function validateMany(&$data, $options = array()) {
21682180
* )
21692181
* }}}
21702182
* - deep: If set to true, not only directly associated data is saved, but deeper nested associated data as well.
2183+
* - callbacks: See Model::save()
2184+
* - counterCache: See Model::save()
21712185
*
21722186
* @param array $data Record data to save. This should be an array indexed by association name.
21732187
* @param array $options Options to use when saving record data, See $options above.

lib/Cake/Test/Case/Model/ModelWriteTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,28 @@ public function testCounterCacheMultipleCaches() {
534534
$this->assertEquals(1, $result[1]['User']['posts_published']);
535535
}
536536

537+
/**
538+
* Tests that counter caches are unchanged when using 'counterCache' => false
539+
*
540+
* @return void
541+
*/
542+
public function testCounterCacheSkip() {
543+
$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
544+
$User = new CounterCacheUser();
545+
$Post = new CounterCachePost();
546+
547+
$data = $Post->find('first', array(
548+
'conditions' => array('id' => 1),
549+
'recursive' => -1
550+
));
551+
$data[$Post->alias]['user_id'] = 301;
552+
$Post->save($data, array('counterCache' => false));
553+
554+
$users = $User->find('all', array('order' => 'User.id'));
555+
$this->assertEquals(2, $users[0]['User']['post_count']);
556+
$this->assertEquals(1, $users[1]['User']['post_count']);
557+
}
558+
537559
/**
538560
* test that beforeValidate returning false can abort saves.
539561
*

0 commit comments

Comments
 (0)