HasMany - save association data

Hello, I need help.
I have a two tables business_departments and companies with association type hasMany.
I need to modify companies list consisting in the department. Code was generated via bake, after that I modified it.

Controller
$businessDepartment = $this->BusinessDepartments->get($id, [
    'contain' => ['Companies']
]);
$companies = $this->BusinessDepartments->Companies->find('list')->where([
    'Companies.active' => true, 
    'Companies.type IS NOT' => 'service', 
    'OR' => [
        'business_department_id IS NULL',
        'business_department_id' => $id
    ]
])->distinct('Companies.id');
if ($this->request->is(['patch', 'post', 'put'])) {
    debug($this->request->getData());
    $businessDepartment = $this->BusinessDepartments->patchEntity($businessDepartment, $this->request->getData(), ['associated' => ['Companies']]);
    debug($businessDepartment);
    if ($this->BusinessDepartments->save($businessDepartment)) {
        $this->Flash->success(__('The business department has been saved.'));

        return $this->redirect(['action' => 'index']);
    }
    $this->Flash->error(__('The business department could not be saved. Please, try again.'));
}
$this->set(compact('businessDepartment', 'companies'));
Entity
protected $_accessible = [
    'name' => true,
    'companies' => true
];
Table
$this->hasMany('Companies', [
    'foreignKey' => 'business_department_id',
    // Tried it
    /*'dependent' => true,
    'cascadeCallbacks' => true,
    'saveStrategy' => 'replace'*/
]);
template
echo $this->Form->control('companies._ids', ['options' => $companies, 'multiple' => true, 'class' => 'multiple-find']);

First save with added companies is success, but when I tried to modify companies list (And if try to save without changes) I get error.
Can I save via *._ids or I need to make a custom code for it?
Thank you. I hope for quick answer.

_ids should work, assuming CakePHP 3.x. We’ll need more details of what you’re trying and what error you’re getting to help resolve it.

Version CakepPHP 3.5.10

Below debug($this->request->getData())

[
    'name' => 'Office',
    'companies' => [
        '_ids' => [
            (int) 0 => '21',
            (int) 1 => '29'
        ]
    ]
]

But after patchEntity, instead of searching for companies and changing the bussines_department_id fields in them, patchEnity tries to create new companies and displays an error. Below is a fragment of screenshot. debug($businessDepartment) and screenshot page

Can you help me? I can make custom code, but if this accessible in cakephp 3, I would like to know about it.

So, you have some departments, say A, B and C. And each department has some companies, say department A has companies M and N, B has S and T and C has X, Y and Z. And you’re trying to move company M from department A to department B?

No. There are several departments and several companies. I need to add and remove companies from the editing department (not move them). When you first edit, I select the necessary companies and their business_department_id changes, with subsequent saving of the entity, an error occurs.

So, companies can belong to multiple departments?

No, Companies can belong to one department, department can has many companies. So I need to change business_department_id into companies table from business department editing. Usually I change foreignKey from entity in wich it located. As I wrote before, I can make custome code, but if _ids is working, I would like a use it. Have a nice day.

Sorry, how is this different from the A/B/C scenario I posted earlier?

you have validation errors in your company related data, thats why you cant save it, if you want to just use _ids as save try clearing companies field in your $businessDepartment i.e.

   $businessDepartment->unsetProperty('companies');

before patchEntity

1 Like

Thank you, it’s working :+1:. But why first save is success? :thinking:

first save is success because

$businessDepartment = $this->BusinessDepartments->get($id, [
    'contain' => ['Companies']
]);

gives you empty ->companies and there are no validation errors in there : )