CakePHP 2.0 HABTM 添加和删除行为

使用此行为来增量添加/删除 HABTM 关联记录的简便方法是,由 Brandon Parise 编写的:HABTM 添加和删除行为(发布日期:2007 年 5 月 9 日) 但是,由于它是在 CakePHP v1.2 时代编写的,因此它似乎在 CakePHP 框架的当前头部版本(即 2.0.x)中出现故障 - 所以我在这里提出了一些修正。

CakePHP 2.0.x ExtendAssociationsBehavior 的更新版本

补丁/差异

$ diff -u old new
--- Vendor/Model/Behavior/ExtendAssociationsBehavior.php    2012-01-10 23:31:14.000000000 +0900
+++ Vendor/Model/Behavior/ExtendAssociations2Behavior.php   2012-01-10 23:33:57.000000000 +0900
@@ -1,5 +1,6 @@
 <?php
-class ExtendAssociationsBehavior extends ModelBehavior {
+App::uses('ModelBehavior', 'Model');
+class ExtendAssociations2Behavior extends ModelBehavior {
     /**
      * Model-specific settings
      * @var array
@@ -44,7 +45,7 @@
             // important to use array_unique() since merging will add
             // non-unique values to the array.
             $data[$assoc][$assoc] = array_unique(am($data[$assoc][$assoc], $assoc_ids));
-            return $model->save($data);
+            return $model->save($data, array('fieldList'=>array($assoc)));
         }

         // association doesn't exist, return false
@@ -82,7 +83,7 @@
                 // which is the ones we want to re-save.
                 $data[$assoc][$assoc] = array_diff($data[$assoc][$assoc], $assoc_ids);
             }
-            return $model->save($data);
+            return $model->save($data, array('fieldList'=>array($assoc)));
         }

         // association doesn't exist, return false
@@ -122,7 +123,7 @@

         // unbind all models except the habtm association
         $this->unbindAll($model, array('hasAndBelongsToMany' => array($assoc)));
-        $data = $model->find(array($model->name.'.'.$model->primaryKey => $id));
+        $data = $model->findById($id);

         $model->recursive = $tmp_recursive;
         $model->cacheQueries = $tmp_cacheQueries;
@@ -149,8 +150,8 @@
      */
     function unbindAll(&$model, $exceptions = array()) {
         $unbind = array();
-        foreach($model->__associations as $type) {
-            foreach($model->{$type} as $assoc=>$assocData) {
+        foreach($model->_associations as $type) {
+            foreach($model->$type as $assoc=>$assocData) {
                 // if the assoc is NOT in the exceptions list then
                 // add it to the list of models to be unbound.
                 if(@!in_array($assoc, $exceptions[$type])) {
@@ -164,3 +165,4 @@
         }
     }
 }
+

用法

使用方法/方法 API 没有变化

## add
$model->habtmAdd($assoc_name, $from_id, array($to_id1, $to_id2, ...));
e.g. $this->Post->habtmAdd('PostsTag', 1, array(2, 3));

## delete
$model->habtmDelete($assoc_name, $from_id, array($to_id1, $to_id2, ...));
e.g. $this->Post->habtmAdd('PostsTag', 1, array(3));

## delete all
$model->habtmDeleteAll($assoc_name, $from_id);

就这样,感谢 Brian 分享如此酷的行为。