ソースを参照

Merge pull request #57 from ndm2/counter-cache-compatibility

Counter cache compatibility fixes and tests
Mark 11 年 前
コミット
0753f21319

+ 10 - 25
Model/Behavior/SoftDeleteBehavior.php

@@ -97,7 +97,7 @@ class SoftDeleteBehavior extends ModelBehavior {
 
 			foreach ($fields as $flag => $date) {
 				if ($runtime === true || $flag === $runtime) {
-					if (!in_array($flag, $conditions) && !in_array($model->name . '.' . $flag, $conditions)) {
+					if (!in_array($flag, $conditions) && !in_array($model->alias . '.' . $flag, $conditions)) {
 						$query['conditions'][$model->alias . '.' . $flag] = false;
 					}
 
@@ -200,7 +200,8 @@ class SoftDeleteBehavior extends ModelBehavior {
 		$model->set($model->primaryKey, $id);
 		$options = array(
 			'validate' => false,
-			'fieldList' => array_keys($data)
+			'fieldList' => array_keys($data),
+			'counterCache' => false
 		);
 		$result = $model->save(array($model->alias => $data), $options);
 		$this->softDelete($model, $runtime);
@@ -392,39 +393,23 @@ class SoftDeleteBehavior extends ModelBehavior {
 	protected function _getCounterCacheKeys(Model $model, $id) {
 		$keys = array();
 		if (!empty($model->belongsTo)) {
-			foreach ($model->belongsTo as $assoc) {
-				if (empty($assoc['counterCache'])) {
-					continue;
+			$fields = array();
+			foreach ($model->belongsTo as $alias => $assoc) {
+				if (!empty($assoc['counterCache']) && isset($assoc['foreignKey']) && is_string($assoc['foreignKey'])) {
+					$fields[$alias] = $assoc['foreignKey'];
 				}
+			}
 
+			if (!empty($fields)) {
 				$keys = $model->find('first', array(
-					'fields' => $this->_collectForeignKeys($model),
+					'fields' => $fields,
 					'conditions' => array($model->alias . '.' . $model->primaryKey => $id),
 					'recursive' => -1,
 					'callbacks' => false
 				));
-				break;
 			}
 		}
 		return $keys;
 	}
 
-	/**
-	 * Collects foreign keys from `belongsTo` associations.
-	 *
-	 * @param Model $model
-	 * @return array
-	 */
-	protected function _collectForeignKeys(Model $model) {
-		$result = array();
-
-		foreach ($model->belongsTo as $assoc => $data) {
-			if (isset($data['foreignKey']) && is_string($data['foreignKey'])) {
-				$result[$assoc] = $data['foreignKey'];
-			}
-		}
-
-		return $result;
-	}
-
 }

+ 54 - 0
Test/Case/Model/Behavior/SoftDeleteBehaviorTest.php

@@ -148,6 +148,33 @@ class SoftDeleteBehaviorTest extends CakeTestCase {
 	}
 
 	/**
+	 * testSoftDeleteWithMultipleCounterCache
+	 *
+	 * @return void
+	 */
+	public function testSoftDeleteWithMultipleCounterCache() {
+		$this->Post->belongsTo['Category']['counterCache'] = array(
+			'post_count' => array('Post.deleted' => false),
+			'deleted_post_count' => array('Post.deleted' => true)
+		);
+
+		$this->Post->Category->id = 1;
+		$count = $this->Post->Category->field('post_count');
+		$this->assertEquals(2, $count);
+		$count = $this->Post->Category->field('deleted_post_count');
+		$this->assertEquals(0, $count);
+
+		$this->assertFalse($this->Post->softDeleted);
+		$this->Post->delete(1);
+		$this->assertTrue($this->Post->softDeleted);
+
+		$count = $this->Post->Category->field('post_count');
+		$this->assertEquals(1, $count);
+		$count = $this->Post->Category->field('deleted_post_count');
+		$this->assertEquals(1, $count);
+	}
+
+	/**
 	 * testSoftDeleteWithoutCounterCache
 	 *
 	 * @return void
@@ -179,6 +206,33 @@ class SoftDeleteBehaviorTest extends CakeTestCase {
 	}
 
 	/**
+	 * testUnDeleteWithMultipleCounterCache
+	 *
+	 * @return void
+	 */
+	public function testUnDeleteWithMultipleCounterCache() {
+		$this->Post->belongsTo['Category']['counterCache'] = array(
+			'post_count' => array('Post.deleted' => false),
+			'deleted_post_count' => array('Post.deleted' => true)
+		);
+
+		$this->Post->Category->id = 2;
+		$count = $this->Post->Category->field('post_count');
+		$this->assertEquals($count, 0);
+		$count = $this->Post->Category->field('deleted_post_count');
+		$this->assertEquals($count, 1);
+
+		$this->assertEmpty($this->Post->read(null, 3));
+
+		$this->Post->undelete(3);
+
+		$count = $this->Post->Category->field('post_count');
+		$this->assertEquals(1, $count);
+		$count = $this->Post->Category->field('deleted_post_count');
+		$this->assertEquals(0, $count);
+	}
+
+	/**
 	 * testUnDeleteWithoutCounterCache
 	 *
 	 * @return void

+ 3 - 0
Test/Fixture/SoftDeleteCategoryFixture.php

@@ -13,6 +13,7 @@ class SoftDeleteCategoryFixture extends CakeTestFixture {
 	public $fields = array(
 		'id' => array('type' => 'integer', 'key' => 'primary'),
 		'post_count' => array('type' => 'integer'),
+		'deleted_post_count' => array('type' => 'integer'),
 		'title' => array('type' => 'string', 'null' => false));
 
 	/**
@@ -24,10 +25,12 @@ class SoftDeleteCategoryFixture extends CakeTestFixture {
 		array(
 			'id' => 1,
 			'post_count' => 2,
+			'deleted_post_count' => 0,
 			'title' => 'Category A'),
 		array(
 			'id' => 2,
 			'post_count' => 0,
+			'deleted_post_count' => 1,
 			'title' => 'Category B'));
 
 }