I cannot seem to be able to save associated data.
In my case, apparent changes to ServiceLineEntries
can be seen, but aren't saved. Parent object (Requests
) field is being saved and works as intended.
Output of code below:
starting at 4/10/24, 11:04 a.m.
project_manager: '', dirty: n
project_manager: 'Overflow, Stack', dirty: y
id: 24326, service_line_stage_id dirty: n
id: 24327, service_line_stage_id dirty: n
loop a - id: 24326, service_line_stage_id: 2, dirty: y
loop a - id: 24327, service_line_stage_id: 2, dirty: y
project_manager: 'Overflow, Stack'
loop b - id: 24326, service_line_stage_id: 1
loop b - id: 24327, service_line_stage_id: 1
Code:
public function myTest ()
{
/*
Requests Entity
* @property \App\Model\Entity\ServiceLineEntry[] $service_line_entries
protected $_accessible = [
'service_line_entries' => true,
];
Requests Table
* @property \App\Model\Table\ServiceLineEntriesTable&\Cake\ORM\Association\HasMany $ServiceLineEntries
ServiceLineEntries Entity
protected $_accessible = [
...
'service_line_stage_id' => true,
...
];
ServiceLineEntries Table
* @property \App\Model\Table\RequestsTable&\Cake\ORM\Association\BelongsTo $Requests
*/
echo "starting at ".FrozenTime::now()."<br/>";
//get record with association
$request = $this->Requests->get(69311, [
'contain' => [
'ServiceLineEntries',
],
]);
//set project_manager
echo "project_manager: '".$request->project_manager."', dirty: ".($request->isDirty('project_manager')?"y":"n")." <br/>";
$request->project_manager = "Overflow, Stack";
echo "project_manager: '".$request->project_manager."', dirty: ".($request->isDirty('project_manager')?"y":"n")." <br/>";
//set service_line_stage_id
foreach($request->service_line_entries as &$e)
{
echo "id: ".$e->id.", service_line_stage_id dirty: ".($e->isDirty('service_line_stage_id')?"y":"n")."</br>";
$e->service_line_stage_id = 2;
unset($e);
//$e->setDirty('service_line_stage_id', true); doesn't help, isDirty() later seems to be true
}
//display value
foreach($request->service_line_entries as $e)
{
echo "loop a - id: ".$e->id.", service_line_stage_id: ".$e->service_line_stage_id.", dirty: ".($e->isDirty('service_line_stage_id')?"y":"n")."</br>";
}
//save
if($this->Requests->save($request, ['associated' => ['ServiceLineEntries']]))
{
//fetch fresh record with association
$request2 = $this->Requests->get(69311, [
'contain' => [
'ServiceLineEntries',
],
]);
//display
echo "project_manager: '".$request->project_manager."'<br/>";
foreach($request2->service_line_entries as $e)
{
echo "loop b - id: ".$e->id.", service_line_stage_id: ".$e->service_line_stage_id."</br>";
}
}
//no view, quit
exit;
}
It seems like the changes to the ServiceLineEntries
associated data are not being saved. To ensure the changes are tracked and saved properly, you need to manually mark the property that holds the nested entities as dirty. In this case, you can use $request->setDirty('service_line_entries', true);
before saving the Requests
entity with associated ServiceLineEntries
. This will help CakePHP ORM track the changes and save them correctly.