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

时间:2009-02-17 20:29:01

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

我正在尝试使用has更新表,并且属于许多(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->项目更新表格>保存($ 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;

当我保存$ data时,我还想保存用户ID。单个保存操作中的所有记录的用户ID都相同。

有人可以帮我理解$ data数组需要的内容才能合并用户ID吗?感谢。

2 个答案:

答案 0 :(得分:2)

这应该有效:

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
                        )

                )

        )

)

它将生成多个INSERT,但可以使用一个保存调用。

答案 1 :(得分:1)

CakePHP的model :: save()方法不会为你做AFAIK。我认为你必须使用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中完成所有操作,因此只有在Item数据验证时才会尝试。

基本上,我们暂时取消绑定beforeSave中的Item hasAndBelongsToMany Label关联,因此HABTM数据不会被保存,我们将HABTM数据存储在模型的属性中,因此我们可以在afterSave中使用它(尽管它可能仍然存在)无论如何都可用。)

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

它应该在理论上运作 - 祝你好运,让我知道你是如何得到的; - )