Database 并非所有联接表列都是外键时保存HABTM记录

Database 并非所有联接表列都是外键时保存HABTM记录,database,cakephp,has-and-belongs-to-many,Database,Cakephp,Has And Belongs To Many,我正在尝试更新具有has和BELLING many(HABTM)关系的表 当我的联接表如下所示时: CREATE TABLE IF NOT EXISTS `items_labels` ( `item_id` int(11) NOT NULL, `label_id` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 我使用CakePHP,因此可以使用$this->Item->save($data)更新表,其中$data是: Ar

我正在尝试更新具有has和BELLING many(HABTM)关系的表

当我的联接表如下所示时:

CREATE TABLE IF NOT EXISTS `items_labels` (
  `item_id` int(11) NOT NULL,
  `label_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
我使用CakePHP,因此可以使用$this->Item->save($data)更新表,其中$data是:

Array
(
    [Item] => Array
        (
            [id] => 1
        )
    [Label] => Array
        (
            [Label] => Array
                (
                    [0] => 4
                    [1] => 5
                    [2] => 7
                    [3] => 8
                )
        )
)
我已将一列添加到联接表中,因此它现在看起来像:

CREATE TABLE IF NOT EXISTS `items_labels` (
  `item_id` int(11) NOT NULL,
  `label_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
保存$数据时,我还想保存一个用户id。在一次保存操作中,所有记录的用户id都相同

有人能帮我理解$data数组需要什么样的外观才能合并用户id吗?谢谢。

CakePHP的model::save()方法暂时无法完成这项工作。我认为您必须使用model::saveAll()并在“with”模型上调用它。CakePHP可以自动识别联接表,并且可以对其进行建模,而无需自己创建物理模型文件和类。您所要做的就是以saveAll期望的格式格式化数据数组

我还没有尝试过,但是下面的方法应该可以奏效

<?php
class Item extends AppModel {
  var $name = 'Item';
  var $_habtmData = null;
  function beforeSave() {
    $this->unbindModel(array('hasAndBelongsToMany' => array('Label')));
    $this->_habtmData = $this->data['Label'];
  }
  function afterSave() {
    if (is_array($this->_habtmData) && !empty($this->_habtmData)) {
      foreach ($this->_habtmData['Label'] as $k => $labelId) {
        $this->_habtmData['Label'][$k] = array(
          'item_id' => $this->id,
          'label_id' => $labelId,
          'user_id' => $userId, // Get this from somewhere
        );
      }
      $this->bindModel(array('hasMany' => array('ItemsLabel')));
      $this->ItemsLabel->saveAll($this->_habtmData);
    }
  }
}
?>

这一切都是在模型中完成的(应该如此),因此控制器和视图保持干净。我们都是在afterSave中完成的,所以只有在项目数据验证后才会尝试

本质上,我们在beforeSave中临时解除项目HasandBelongToMany标签关联的绑定,因此不会保存HABTM数据,我们将HABTM数据存储在模型的一个属性中,这样我们就可以在afterSave中使用它(尽管那时它可能仍然可用)

然后,我们将“with”模型绑定到具有hasMany关联的项,并按照CakePHP的核心模型::saveAll()方法的要求格式化数据,最后在“with”模型上调用它,传递新数据

从理论上讲应该是可行的——祝你好运,让我知道你进展如何;-)

这应该有效:

Array
(
    [Item] => Array
        (
            [id] => 1
        )

    [Label] => Array
        (
            [Label] => Array
                (
                    [0] => Array
                        (
                            [label_id] => 4
                            [user_id] => 1
                        )

                    [1] => Array
                        (
                            [label_id] => 5
                            [user_id] => 1
                        )

                    [2] => Array
                        (
                            [label_id] => 7
                            [user_id] => 1
                        )

                    [3] => Array
                        (
                            [label_id] => 8
                            [user_id] => 1
                        )

                )

        )

)

它将生成多个插入,但只能使用一个保存调用。

将“mysql”标记替换为“cakephp”。嘿,谢谢你的详细回答。马特·库里(Matt Curry)的方法对我很有效,而且简单得多。我已将您的答案添加到书签中,因为如果遇到更复杂的HABTM数据,这可能会很有用。嗨,马特,我以前读过您的博客。很高兴在这里得到你的答复。谢谢