I am currently using CakePHP to serve a crud based api for some ticketing logic I wrote. I am running into an issue where I am attempting to change a belongsTo association and data within the new association and it is not persisting.
The controller doing the persisting looks like this:
<?php
class TasksController extends Cake\Controller\Controller
{
public function initialize()
{
parent::initialize();
}
public function edit(array $ids): void
{
$validationErrors = [];
$tasks = $this->Tasks->find('all')
->contain($this->setAssociations($query))
->where([$this->Model->getAlias().'.id IN' => $ids]);
foreach ($tasks as $id => $task) {
$this->Tasks->patchEntity($task, $this->request->getQuery()[$id], [
'associated' => ['Asset']
]);
}
if ($this->Tasks->saveMany($tasks)) {
$this->response = $this->response->withStatus(200);
} else {
// Handle errors
}
// Render json output for success / errors
$this->set($this->createViewVars(['entities' => $tasks], $validationErrors));
}
}
The association for an asset in the task table looks like this:
<?php
class TasksTable extends Cake\ORM\Table
{
public function initialize(array $config)
{
$this->belongsTo('Asset', [
'className' => 'Assets',
'foreignKey' => 'asset_id',
'joinType' => 'LEFT'
]);
}
}
These build rules are attached to the asset table:
<?php
class AssetsTable extends Cake\ORM\Table
{
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['number', 'group_id'], 'The Number you selected is in use'));
$rules->add($rules->isUnique(['name', 'group_id'], 'The Name you selected is in use'));
}
}
The body of the request I am sending looks like this:
{
"421933": {
"description": "This task was edited by the api!",
"asset": {
"id": "138499",
"description": "This asset was edited by they api!",
"name": "105",
"number": "6"
}
}
}
Basically the name 105 and number 6 are being flagged as not being unique, because they are already set to those values on asset 138499. The query is is instead trying to edit name 105 and number 6 into the Asset entity that is presently associated with the Task entity (645163), which is triggering the isUnquie build rules to fail.
You can see this by printing the $tasks before the saveMany call in the above controller:
Array
(
[0] => App\Model\Entity\Task Object
(
[id] => 421933
[description] => This task was edited by the api!
.....
[asset] => App\Model\Entity\Asset Object
(
[id] => 645163
[name] => 105
[description] => This asset was edited by they api!
[number] => 6
....
)
)
)
It seems like this editing Asset 138499 as an association of Task 421933 should work as it is appears to be possible to save belongsTo associations in this fashion in the CakePHP docs, as documented here:
<?php
$data = [
'title' => 'First Post',
'user' => [
'id' => 1,
'username' => 'mark'
]
];
$articles = TableRegistry::getTableLocator()->get('Articles');
$article = $articles->newEntity($data, [
'associated' => ['Users']
]);
$articles->save($article);
Is it possible to associate a belongsTo association and edit it in the same transaction? If so how should my request or code be structured differently?
Thanks!
patchEntities()
for patching multiple entities at once. ps. yoursaveMany()
calls seem to reference only the last entity, that looks wrong and should make saving not work at all - please make sure that you're not modifying your code too much (if at all) when posting it here, as that might hide possible problems! – ndmhasMany
association there) and editing it at the same time doesn't work, as the marshaller will only merge the data, while it would have to load the new record, replace the existing entity, and merge the data into the new entity for this to work properly. – ndmbelongsTo
, so I'm not sure what you mean by "changing" that? – ndm