-1

我正在尝试更新具有并属于许多(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;

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

有人可以帮助我了解 $data 数组需要是什么样子才能合并用户 ID 吗?谢谢。

4

2 回答 2

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,但将使用一个保存调用。

于 2009-02-18T22:42:18.487 回答
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 中使用它(尽管它可能仍然可用) )。

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

它应该在理论上有效 - 祝你好运,让我知道你的进展;-)

于 2009-02-18T21:36:22.170 回答