【问题标题】:CakePHP deletes other HABTM records on saveAllCakePHP 删除 saveAll 上的其他 HABTM 记录
【发布时间】:2011-07-03 04:54:54
【问题描述】:

我有两个与 HABTM 相关的模型:缺席和用户。对于上下文,用户申请缺勤(因此,用户别名为申请人,缺勤别名为缺勤申请)。我正在尝试为“应用”和“收回”创建控制器功能,这将分别添加一条 HABTM 记录和删除一条 HABTM 记录。我已经将代码保存到可以保存一条记录的地步,但不再保存了。现在我的“应用”控制器代码被硬编码以添加几条记录,但它只添加最后一个请求的记录。这是我的控制器代码:

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

【问题讨论】:

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


    【解决方案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.。如果你这样做了,你以后会爱上自己的。

    【讨论】:

    • 我看到了关于连接的单独模型的部分,但没有把它放在一起,这是我需要的。看起来是一个可靠的方法。谢谢!
    • 谢谢!如果这对你不起作用,请告诉我。我喜欢我的答案真正解决问题。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多