Cake 3: How to add a new object to the database using primaryKey?

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 their primaryKeys sets which values ​​should be stored. My code is:

$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 wonder if there is a better solution?

To clarify: I want to add something like

  [ ['id' => 25, 'title'=>'some title'], ['id'=> 3, 'title' => 'some other title'], ['id' => 4356, 'title' => 'another title'] ] 

into my empty database. findOrCreate () does the job. But I think that there is no need to check every record that it does not already exist in the database before inserting.

+6
source share
2 answers

If you really only work with empty tables, you can just save the data right away, no need to search and fix, just save with the existence check disabled.

Also, looking at your code, the data seems to be in a format that you can immediately convert to objects, so you can create them all at once.

 $entities = $table->newEntities($data, [ // don't forget to restrict assignment one way or // another when working with external input, for // example by using the `fieldList` option 'fieldList' => [ 'id', 'title' ] ]); // you may want to check the validation results here before saving foreach ($entities as $entity) { if ($table->save($entity, ['checkExisting' => false])) { // ... } // ... } 

see also

+3
source

A common problem with records that have mysteriously lost some of the data provided to the new Entity is that Entity does not define the fields in question as _accessible .

Cake 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 several ways 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 set your call to newEntity() to disable mass assignment protection:

 $entities = $table->newEntity($data, [ 'accessibleFields' => ['id' => true], ]); 

I found the most important damage when you are having problems with Cake 3 DB data is to double-check Entity as soon as it is created or fixed, and compare it with your input. You should still have a keen eye, but it will be shown that the objects did not have their property ->id , even if $data defined them.

+6
source

Source: https://habr.com/ru/post/982107/


All Articles