使用主模型保存 HABTM 数据的另一种方法

CakePHP 文档中关于保存 HABTM 数据的部分没有涵盖我的应用程序需要的用例。我的表单提交了一个与用户一起保存的关联模型 ID 的逗号分隔列表。通过一些数据格式调整,我找到了一种方法,可以通过一次调用 Model->save(…)来保存所有内容。

我的应用程序有一个模式,其中 User 模型和 Equipment 模型共享 HABTM 关系。换句话说,一个或多个用户可能是一个或多个设备的联络人。由于已经存在超过 100 件设备,因此在 User 编辑表单上使用多选下拉列表或复选框来选择 Equipment 可能会在应该是一个简单表单的表单上变得笨拙且难以使用。因此,我采用了不同的方法,使用自动完成编辑框。当用户键入部分名称并从显示的匹配项中选择一件设备时,它会将该设备显示在与该用户关联的设备列表中,以及一个小的“x”图标,允许他再次将其移除。使用自动完成框和“x”图像链接,他可以添加或删除设备列表中的设备,直到他准备提交表单。

当用户提交表单时,Javascript 提交事件处理程序会生成一个形式为“1,2,3,4…”的 ID 数组,并将其插入到一个隐藏字段中,该字段与表单一起提交。

因此,Controller->request->data 将类似于以下内容

$data = array(
  'Equipment' => '37,97,98',
  'User' => array(
    'id' => '99',
    'username' => 'testuser1',
    'fullname' => 'Test User',
    'phone' => '222-2222',
    'email' => '[email protected]',
    'Role' => '2'
  ),
);

我需要将该“Equipment”元素转换为以下内容

'Equipment' => array(37, 97, 98)

这很容易

$data['Equipment'] = array_split(',', $data['Equipment']);

现在我可以将 User 与他相关的设备列表一起保存

$result = $this->User->save($data, array(
  'validate' => true,
  'fieldList' => null,
));

我花时间发布这一点,因为我在此方面挣扎了很长时间。文档似乎表明我需要发布一个像这样的数组

$data = array(
  'Equipment' => array(
      array('equipment_id' => 37),
      array('equipment_id' => 97),
      array('equipment_id' => 98),
  ),
  'User' => array(
    'id' => '1',
    'username' => 'testuser1',
    'fullname' => 'Test User',
    'phone' => '222-2222',
    'email' => '[email protected]',
    'Role' => '2'
  ),
);

这导致 Cake 核心为 equipment_id=37 生成一个插入语句,然后为 ID 97 和 98 生成两个更新语句。因此,最终结果是查询

select * from equipment_users where user_id = 99

只会产生

array(
(int) 0 => array(
    'equipment_users' => array(
        'equipment_id' => '98',
        'user_id' => '1'
    )
)
)

而不是想要的

array(
(int) 0 => array(
    'equipment_users' => array(
        'equipment_id' => '98',
        'user_id' => '1'
    )
),
(int) 1 => array(
    'equipment_users' => array(
        'equipment_id' => '37',
        'user_id' => '1'
    )
),
(int) 2 => array(
    'equipment_users' => array(
        'equipment_id' => '97',
        'user_id' => '1'
    )
)
)

我希望这能帮到别人。我还希望 CakePHP 文档的常规贡献者之一能与我合作,找到一种方法将此用例包含在关于 Saving Your Data 的章节中。