Klaus
December 6, 2022, 3:56pm
1
Hallo,
I have a function in the Model Table saving new records. This was used in Cake 3 for years.
Now as I am on Cake 4 I recognize problems, the data are not stored and some other curious things happen. I have changed from newEntety to newEmptyEntety.
Error: Cake\ORM\Table::save() must implement interface Cake\Datasource\EntityInterface, instance of stdClass given.
The model includes:
use Cake\Datasource\EntityInterface;
What is the correct usage and where do have look for the error?
Kind regards
$ready = true;
$numbers = array();
$numbers[] = $newYear;
$ccTable = TableRegistry::get('Costcenters');
$heute = getdate();
foreach ($tags as $key => $value) {
$orgkey = str_replace('Field', '', $key);
$account = $this->find()
->where(['account_no' => $orgkey])
->where(['year' => $newYear -1])
->toList();
$numbers[] = $orgkey;
$ewAccount = $this->newEmptyEntity();
$newAccount->account_no = $account[0]['account_no'];
$newAccount->frame_id = $account[0]['frame_id'];
$newAccount->category_id = $account[0]['category_id'];
$newAccount->name = $account[0]['name'];
$newAccount->year = $newYear;
$newAccount->closed = 0;
$newAccount->start = 0;
$newAccount->end = 0;
$newAccount->actTrans = 0;
$newAccount->pasTrans = 0;
$newAccount->budget = 0;
$newAccount->created = $heute;
$numbers[] = $newAccount->name;
$this->save($newAccount);
}
What you are trying to do here should be done in some sort of service outside of the model.
See CakeFest Virtual 2021 Day 2 - How to re use code: Utility Classes and PHP Namespaces - Kevin Pfeifer - YouTube on how to do that.
Calling ->save()
inside the table class itself is really not recommended.
Regarding the typical create and patch methodology
i would recommend something like this
foreach ($items as $item) :
$entity = $this->MyModelTableClass->find()
->where(['some_field_ident' => $identifier])
->first();
// Update or create depending if the given entity is already present
if (!$entity instanceof MyModelEntityClass) {
$entity = $this->MyModelTableClass->newEmptyEntity();
}
$data = [
'some_field_ident' => $item['identifier'],
'other_field' => $item['otherField',
// add more fields here
];
$entity = $this->MyModelTableClass->patchEntity($entity, $data);
if ($this->MyModelTableClass->save($entity)) {
// Success
} else {
// Somethings wrong
$outcome['error'][] = $entity->getErrors();
}
$touchedIds[] = $item['identifier'];
endforeach;
// Check touched_ids with ids currently in db
if (!empty($touchedIds)) :
$dbEntries = $this->MyModelTableClass->find('list', [
'valueField' => 'some_field_ident',
])
->toArray();
$diff = array_diff($dbEntries, $touchedIds);
if (!empty($diff)) :
$this->MyModelTableClass->deleteAll(['some_field_ident IN' => $diff]);
endif;
endif;
some_field_ident
should be something unique inside your entries
Hello.
I think the problem is corrected by changing these lines to the following:
For this other one:
$newAccount = $this->ModelName->newEmptyEntity();
This line creates a new empty model entity.
Then change this other line
for this other one:
$this->ControllerName->save($newAccount);
The rest of the code has functional logic.
In CakePHP 4, controllers and models must be called in order to manipulate them, like so:
Controller:
$this->controllerName->actionName
Model:
$this->modelName->actionName
I hope this information helps you.
Klaus
December 14, 2022, 10:35pm
4
Thanks for your input. I have moved the function from the Model into a Component und I am happy with your suggestions. Klaus