CakePHP删除saveAll上的其他HABTM记录

时间:2011-07-03 04:54:55

标签: cakephp has-and-belongs-to-many

我有两个与HABTM相关的模型:缺勤和用户。对于上下文,用户申请缺席(因此,用户对申请人有别名,缺席是缺席申请)。我正在尝试为'apply'和'retract'创建控制器函数,它们将分别添加HABTM记录并删除HABTM记录。我已经得到了代码,它将保存一条记录,但不会更多。现在我的'apply'控制器代码被硬编码以添加几个记录,但它只添加了最后一个请求。这是我的控制器代码:

function apply($id = null) {
            if (!$id) {
                    $this->Session->setFlash(__('Invalid id for absence', true));
                    $this->redirect(array('action'=>'index'));
            }

            $this->Absence->recursive = 1;
            $user = $this->Session->read('User');
            $absence = $this->Absence->read(null, $id);
            $data = array(
                    array(
                            'Applicant' => array('id' => 1),
                            'Absence' => array('id' => 4)
                    ),
                    array(
                            'Applicant' => array('id' => 2),
                            'Absence' => array('id' => 4)
                    )
            );

            //$data = array_unique($data);
            if ($this->Absence->saveAll($data)) {
                    $this->Session->setFlash('Application was successful');
            } else {
                    $this->Session->setFlash('Application failed');
            }
            $this->set(compact('data'));
    }

我可以在调试查询中看到$ data中的两个条目都被处理,但由于某种原因,删除了一个条目。谁知道为什么?以下是该控制器代码运行的一些查询(请注意19,25和26):

11  START TRANSACTION       0       0
12  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
13  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
14  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
15  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
16  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
17  UPDATE `absences` SET `id` = 4, `modified` = '2011-07-03 00:28:39' WHERE `absences`.`id` = 4        1       0
18  SELECT `AbsencesUser`.`user_id` FROM `absences_users` AS `AbsencesUser` WHERE `AbsencesUser`.`absence_id` = 4       0   0   0
19  INSERT INTO `absences_users` (`absence_id`,`user_id`) VALUES (4,1)      1       0
20  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
21  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
22  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
23  UPDATE `absences` SET `id` = 4, `modified` = '2011-07-03 00:28:39' WHERE `absences`.`id` = 4        0       0
24  SELECT `AbsencesUser`.`user_id` FROM `absences_users` AS `AbsencesUser` WHERE `AbsencesUser`.`absence_id` = 4       1   1   0
25  DELETE `AbsencesUser` FROM `absences_users` AS `AbsencesUser` WHERE `AbsencesUser`.`absence_id` = 4 AND `AbsencesUser`.`user_id` = (1)          1       1
26  INSERT INTO `absences_users` (`absence_id`,`user_id`) VALUES (4,2)      1       0
27  COMMIT      0       123

2 个答案:

答案 0 :(得分:1)

  

我可以在调试查询中看到$ data中的两个条目都被处理,但由于某种原因,删除了一个条目。谁知道为什么?

当然,因为它是Cake的默认行为。 Read this section about saving data with HABTM.

本节简要介绍如何为您的联接表创建一个单独的模型,但我认为它不能完全解释这意味着什么或如何做。 我并不是说这应该是您的方法,您应该研究信息并根据您的应用做出决定!数据原理图很容易成为最重要的方面之一。

我不熟悉Ruby on Rails,但实质上我们想要复制RoR's has_many :through模型关联。简而言之,我们希望能够像使用任何其他模型一样使用HABTM join表。

所以,我们会像这样设置我们的新模型关联

您的Absence型号......

class Absence extends AppModel {

    public $belongsTo = array('AbsentUser');
    ...

您的User型号......

class User extends AppModel {
    public $belongsTo = array('AbsentUser');
    ...

您的 AbsentUser模型......

class AbsentUser extends AppModel {
    public $hasMany = array('Absence', 'User');
    ...

现在您可以使用AbsentUser作为自己的模型,允许您绕过Cake的默认HABTM行为。此外,如果您愿意,它还允许您轻松扩展AbsentUser数据以包含其他字段。例如,您可以存储有关特定缺席的特定信息。

我强烈建议您确保fat models and skinny controllers.。如果你这样做,你最终会爱上自己。

答案 1 :(得分:0)

从版本2.1开始,您现在可以将唯一设置设置为 keepExisting ,以避免在保存操作期间丢失额外数据。

 var $hasAndBelongsToMany = array(
        'User'  => array(
            'unique' => 'keepExisting',
            ),
    );