I want to populate my database with 'flat' data extracted from an excel sheet. All records are provided as arrays (similar to $request->data) but have their primaryKeys set which values must be kept. My code:
$imported = 0;
foreach ($data as $record) {
$entity = $table->findOrCreate([$table->primaryKey() => $record[$table->primaryKey()]]);
$entity = $table->patchEntity($entity, $record);
if ($table->save($entity)) {
$imported++;
}
}
The code works, but I'm wondering if there is a better solution?
To clarify: What I want is adding something like
[
['id' => 25, 'title'=>'some title'],
['id'=> 3, 'title' => 'some other title'],
['id' => 4356, 'title' => 'another title']
]
to my empty database. findOrCreate() does the job. But I think it shouldn't be necessary to test every record that it not already exists in database before inserting.
A common problem with records mysteriously losing some of the data being provided to a new Entity
is that the Entity does not define the field(s) in question as _accessible
.
Cake's BakeShell will skip the primary key fields when generating new Entity classes for you, for example:
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
/**
* Widget Entity.
*/
class Widget extends Entity {
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* @var array
*/
protected $_accessible = [
// `id` is NOT accessible by default!
'title' => true,
];
}
There are a few ways to work around this.
You can modify your Entity class to make the id
field permanently assignable:
protected $_accessible = [
'id' => true, // Now `id` can always be mass-assigned.
'title' => true,
];
Or you can adjust your call to newEntity()
to disable mass assignment protection:
$entities = $table->newEntity($data, [
'accessibleFields' => ['id' => true],
]);
I've found the most important take-away when you're having issues with Cake 3 DB data is to double-check the Entity as soon as it's created or patched and compare it against your input data. You still need to have a sharp eye, but doing so would reveal that the Entities did not have their ->id
property set at all even though $data
defined them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With