我有2个模型,Client
和Security
。它们与HATBTM关系相关联。
我创建了一个名为clients_securities
的连接表。因此,Client
可以拥有多个证券,Security
可以属于许多Client
个。
以下是我的关系定义:
//Client Model:
public $hasAndBelongsToMany = array(
'Security' =>
array(
'className' => 'Security',
'joinTable' => 'clients_securities',
'foreignKey' => 'client_id',
'associationForeignKey' => 'security_id',
'unique' => true,
)
);
//Security Model:
public $hasAndBelongsToMany = array(
'Client' =>
array(
'className' => 'Client',
'joinTable' => 'clients_securities',
'foreignKey' => 'security_id',
'associationForeignKey' => 'client_id',
'unique' => true,
)
);
然后我在我的客户控制器中进行了编辑操作并执行了此操作:
public function edit($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid client'));
}
$client = $this->Client->findById($id);
if (!$client) {
throw new NotFoundException(__('Invalid client'));
}
if ($this->request->is('post') || $this->request->is('put')) {
$this->Client->id = $id;
if ($this->Client->saveAll($this->request->data)) {
$this->Session->setFlash(__('Client has been updated.'));
return $this->redirect(array('action' => 'edit', $id));
}
$this->Session->setFlash(__('Unable to update client.'));
}
if (!$this->request->data) {
$this->request->data = $client;
$this->set('securities', $this->Client->Security->find('list'));
}
}
在我的编辑视图中,我使用HtmlHelper构建表单,添加客户端表字段并生成多个选择:
echo $this->Form->create('Client'); //start the form for the client model
echo $this->Form->input('Security'); //generates a multi-select popuplated with securities
此外,我还以相同的形式为Client
提供了正常的直接表单输入。 e.g。
echo $this->Form->input('name'); //Input for the client name
echo $this->Form->input('currency'); //Input for the client currency
...
在呈现表单时,所有这些输入都会生成并填充正确的值,但只保存直接的客户端数据,而不是多选的HABTM数据。
当我提交表单时,clients_securities
表中没有填充连接ID。
我需要做些什么才能正确保存,然后在重新加载“编辑”视图时预先选择保存的证券。
修改:为了澄清事情,这里是pr()
$this->request->data
。
(值(“ALLCMCT LX Equity”)是securities
表的正确外键:
Array
(
[Client] => Array
(
[id] => 1212
[name] => Example Client
[currency] => GBP
[partner] =>
[risk_category_id] => 4
[client_code_id] => 1
[min_cash_balance] => 0
[active] => 1
[model] => 0
[institutional] => 0
[non_uk_situs] => 0
[reporting_status] => 0
)
[Security] => Array
(
[Security] => Array
(
[0] => .1muslib3 index
[1] => .eurib3 index
[2] => .ukcpi2 index
)
)
)
基本上,假设我的客户端ID是12345,Cake应该在clients_securities
表中插入2条记录,如下所示:
id | client_id | security_id
----------------------------
1 | 12345 | ALLCMCT LX Equity
2 | 12345 | APMKNTD LX Equity
如果我手动将一些联接记录添加到clients_securities
,当我去编辑客户端时,多选中的证券会正确预选,显示正在从联接表中读取数据。当我保存表单时,它实际上删除了连接记录,但没有保存新的。
附加说明:如果有任何影响,我的安全ID将存储为CHAR(36)。这不是自动增量字段,它包含安全性的代码,每个字段都是唯一的。
答案 0 :(得分:5)
答案 1 :(得分:1)
修改表单输入,如下所示:
echo $this->Form->input('Security.Security');
答案 2 :(得分:0)
<?php
Model::saveAssociated(array $data = null, array $options = array());
or
Model::saveAll(array $data = null, array $options = array());
?>
有关详细信息,请访问:http://book.cakephp.org/2.0/en/models/saving-your-data.html
答案 3 :(得分:0)
我会试一试......
您忘记了$ this-&gt;客户端 - &gt; read();在$ this-&gt; Client-&gt; id = $ id之后;在edit()函数中($ this-&gt;客户端的内部未初始化,因此在保存完成时不存在client_id)。调用“findById”将只返回一个数组,但不会将数据读取到对象$ this-&gt; Client。
只是一个受过良好教育的猜测..
答案 4 :(得分:0)
也许我错了,但我想您忘记在视图中使用客户端ID创建隐藏输入
echo $this->Form->hidden('Client.id');
答案 5 :(得分:0)
它不是填充的媒体表,因为在填充两个模型之后它没有用于填充媒体表的id。因此用户beforeSave和afterSave函数将填充您的中介表。在客户端模型中添加beforesave函数
public function beforeSave($options = array()) {
parent::beforeSave($options = array());
foreach (array_keys($this->hasAndBelongsToMany) as $model):
if(isset($this->data[$this->alias][$model])):
$this->data[$model][$model] = $this->data[$this->alias][$model];
unset($this->data[$this->alias][$model]);
endif;
endforeach;
return true;
}
在安全用户AfterSave功能中,
public $securityIdArray = array();
public function afterSave($created) {
if($created) {
$this->securityIdArray[] = $this->getInsertID();
}
return true;
}
首先保存安全性并使用$ securityIdArray在$ this-&gt;模型 - &gt;保存在控制器中后获取安全ID。
$this->Security->securityIdArray[] = $void['Security']['id'];
并且是啊@Arilia说修改你的论坛输入字段
echo $this->Form->input('Security.Security');
并且不要为两个模型制作单独的表格