I have 2 models, Client and Security. They are associated with a HATBTM relationship.
I have made a join table called clients_securities. So a Client can have many securities and a Security can belong to many Clients.

Here are my relationship definitions:
//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,
)
);
I then made an edit action in my clients controller and did this:
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'));
}
}
In my edit view I build the form using the HtmlHelper, adding the client table fields and generating the multiple select with:
echo $this->Form->create('Client'); //start the form for the client model
echo $this->Form->input('Security'); //generates a multi-select popuplated with securities
In addition I also have normal direct form inputs for the Client in the same form. e.g.
echo $this->Form->input('name'); //Input for the client name
echo $this->Form->input('currency'); //Input for the client currency
...
All these inputs get generated and populated with the correct values when the form is rendered but only the direct Client data is saved, not the HABTM data from the multi-select.
When I submit the form the clients_securities table is not populated with the join IDs.
What do I need to do to save it correctly and have then have the saved securities be pre-selected when I reload the "edit" view.
Edit: To clarify things, here is a pr() of $this->request->data.
(The values ("ALLCMCT LX Equity") are the correct foreign keys for the securities table):
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
)
)
)
So essentially, say my client id was 12345, Cake should insert 2 records in the clients_securities table like so:
id | client_id | security_id
----------------------------
1 | 12345 | ALLCMCT LX Equity
2 | 12345 | APMKNTD LX Equity
If I manually add some join records into clients_securities, when I go to edit a client the securities in the multi-select come up correctly pre-selected showing that the data is being read from the join table. When I save the form it actually removes the join records but does not save new ones.
Additional note: My security IDs are stored as CHAR(36) if that has any effect. This is not an auto-increment field, it contains the ticker of the security and each is unique.
'unique' => 'keepExisting', instead? Also, I don't think that the ID format is an issue, but just to be sure did you try with a INT fake id? Lastly: could you please post a completepr($this->request->data)(without sensitive data, of course) - arilia$this-request->data. I think I want to keep theuniqueas true as I want the old links to be removed before the new ones are inserted. - harryg