Cake 3:如何使用主键设置将新实体添加到数据库?

时间:2015-02-06 19:18:52

标签: cakephp cakephp-3.0

我想用' flat'填充我的数据库。从Excel工作表中提取的数据。所有记录都以数组形式提供(类似于$ request->数据),但其primaryKeys设置必须保留哪些值。 我的代码:

$imported = 0;  
foreach ($data as $record) {  
    $entity = $table->findOrCreate([$table->primaryKey() => $record[$table->primaryKey()]]);  
    $entity = $table->patchEntity($entity, $record);  
    if ($table->save($entity)) {  
        $imported++;  
    }  
}  

代码有效,但我想知道是否有更好的解决方案?

澄清:我想要的是添加类似

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

到我的空数据库。 findOrCreate()完成这项工作。但我认为在插入之前测试数据库中尚未存在的每条记录是不必要的。

2 个答案:

答案 0 :(得分:6)

记录错误地丢失了提供给新Entity的一些数据的常见问题是,实体未将相关字段定义为_accessible

Cake的BakeShell将在为您生成新的Entity类时跳过主键字段,例如:

<?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,
    ];
}

有几种方法可以解决这个问题。

您可以修改您的实体类,使id字段永久可分配:

    protected $_accessible = [
        'id' => true, // Now `id` can always be mass-assigned.
        'title' => true,
    ];

或者您可以将来电调整为newEntity()以禁用质量指配保护:

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

我发现当你遇到Cake 3数据库问题时,最重要的一点就是在创建或修补后立即仔细检查实体并将其与输入数据进行比较。您仍然需要敏锐的眼光,但这样做会显示实体根本没有设置->id属性,即使$data定义了它们。

答案 1 :(得分:4)

如果您真的只使用空表,那么您可以直接保存数据,无需查找和修补,只需保存已禁用的存在检查。

同样通过查看您的代码,数据似乎是一种可以立即转换为实体的格式,因此您可能希望一次创建它们。

$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])) {
        // ...
    }
    // ...
}

另见