1

我在 CakePHP 中的 HABTM 关系有问题。

我有两个这样的模型:DepartmentHABTM Location。一家大公司有许多建筑物,每栋建筑物提供的服务数量有限。每个建筑物也有自己的网页,因此除了 HABTM 关系本身之外,每个 HABTM 行还有一个url字段,用户可以访问该字段以查找有关他们感兴趣的服务以及它如何在他们所在的建筑物中运行的其他信息有兴趣。

我已经像这样设置模型:

<?php
class Location extends AppModel {
    var $name = 'Location';

    var $hasAndBelongsToMany = array(
        'Department' => array(
            'with' => 'DepartmentsLocation',
            'unique' => true
        )
    );
}
?>


<?php
class Department extends AppModel {
    var $name = 'Department';

    var $hasAndBelongsToMany = array(
        'Location' => array(
            'with' => 'DepartmentsLocation',
            'unique' => true
        )
    );
}
?>

<?php
class DepartmentsLocation extends AppModel {
    var $name = 'DepartmentsLocation';

    var $belongsTo = array(
        'Department',
        'Location'
    );    


    // I'm pretty sure this method is unrelated. It's not being called when this error
    // occurs. Its purpose is to prevent having two HABTM rows with the same location
    // and department.
    function beforeSave() {

        // kill any existing rows with same associations
        $this->log(__FILE__ . ": killing existing HABTM rows", LOG_DEBUG);

        $result = $this->find('all', array("conditions" =>
            array("location_id" => $this->data['DepartmentsLocation']['location_id'],
                  "department_id" => $this->data['DepartmentsLocation']['department_id'])));


        foreach($result as $row) { 
            $this->delete($row['DepartmentsLocation']['id']);
        }

        return true;
    }
}
?>

控制器完全无趣。

问题: 如果我编辑 a 的名称,则链接到该名称的Location所有DepartmentsLocations 都将Location使用空 URL 重新创建。由于模型指定 unique 为真,这也会导致所有较新的行覆盖较旧的行,这实质上会破坏所有 URL。

我想知道两件事:我可以停止吗?如果是这样,怎么做?

而且,在一个不太技术和更多抱怨的情况下:为什么会发生这种情况?对我来说,通过 Cake 编辑字段会引起这么多麻烦,这对我来说似乎很奇怪,因为我可以轻松地通过 phpMyAdmin,在Location那里编辑名称,并得到我期望的结果。当我只是在一行中编辑一个字段时,为什么 CakePHP 会触摸 HABTM 数据?它甚至不是外键!

4

3 回答 3

1

从 CookBook 来看,第一个问题是:

默认情况下,当保存 HasAndBelongsToMany 关系时,Cake 会在保存新行之前删除连接表上的所有行。

即使您的数据中没有外键,我也不太清楚为什么 Cake 会尝试保存 HABTM 数据,但有一个简单的解决方案。只需销毁保存调用的关联:

$this->Location->unbindModel(
    array('hasAndBelongsToMany' => array('Department'))
);
于 2010-02-16T19:40:06.700 回答
1

我在想为什么会发生这种情况的一个原因。当您检索时Location,您也检索locations_departments数据。当您执行 a 时save($this->data),它会在数组中查找模型并保存它们。

解决此问题的一种方法是将recursive(模型的)属性设置为-10(尝试,我不确定,只需打印数据以查看结果)。您可以在模型中设置它:var $recursive = -1;或在控制器方法(动作)中:$this->ModelName->recursive = -1;

更多关于递归:http ://book.cakephp.org/view/439/recursive

它与harpax建议的非常相似,只是如果您不需要该数据,请将其告诉 Cake,这样它就不会获取它。

于 2010-02-16T20:58:02.410 回答
0

麻烦的是,当你保存你的时Location,你给了 save 方法一个包含所有DepartmentsLocations。因此,CakePHP 会破坏一切并尝试重新创建它。

这是蛋糕的常见错误,因为它通常会为您带来太多结果。

确保只传递需要保存的数据,或者最好只获取您需要的数据。

于 2010-05-04T13:26:51.027 回答