CakePHP 3.X - patchEntity 设置外键失败

CakePHP 3.X - patchEntity failed to set foreign key

我试图保存一个 Order 实体,但 patchEntity 总是将两个外键字段设置为 null。

订单与具有 2 个关联(送货和发票)的地址相关联。

关联地址已经存在,所以我只想将地址id作为外键保存到订单中table。

订单表

namespace OrderManager\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use OrderManager\Model\Entity\Order;

/**
 * Orders Model
 */
class OrdersTable extends Table {

/**
 * Initialize method
 *
 * @param array $config The configuration for the Table.
 * @return void
 */
public function initialize(array $config) {
    $this->table('orders');
    $this->displayField('id');
    $this->primaryKey('id');
    $this->addBehavior('Timestamp');

    $this->belongsTo('Contacts', [
        'foreignKey' => 'contact_id',
        'joinType' => 'INNER',
        'className' => 'ContactManager.Contacts'
    ]);

    // ... 

    $this->belongsTo('DeliveryAddresses', [
        'foreignKey' => 'delivery_address',
        'className' => 'ContactManager.Addresses'
    ]);
    
    $this->belongsTo('InvoiceAddresses', [
        'foreignKey' => 'invoice_address',
        'className' => 'ContactManager.Addresses'
    ]);
}

public function validationDefault(Validator $validator) {
    
    // ...

    $validator
            ->add('delivery_address', 'valid', ['rule' => 'numeric'])
            ->allowEmpty('delivery_address');

    $validator
            ->add('invoice_address', 'valid', ['rule' => 'numeric'])
            ->allowEmpty('invoice_address');
    
    // ...
}

控制器

$data = [
    // ...
    'contact_id' => 34,
    'delivery_address' => 8,
    'invoice_address' => 8,
    'currency' => 'Euro',
    'total_paid' => '100.00',
    'shipping_number' => ''
    // ...
];

$entity = $this->Orders->newEntity();
$entity = $this->Orders->patchEntity($entity, $data);
debug($entity);

debug($entity) 总是告诉我:

'delivery_address' => null,

'invoice_address' => null,

当我删除 belongsTo 关联(DeliveryAddresses 和 InvoiceAddresses)时,我的字段获得数值 (8)。但我需要这些联想。

如何保留这些关联并保存外键的数值?

外键名称与关联 属性 名称(存储关联数据的位置)冲突,默认情况下这些名称是从关联名称派生的,如果 belongsTo 一个是关联名称的单数下划线变体,即 delivery_addressinvoice_address.

Cookbook > Database Access & ORM > Associations > BelongsTo Associations

要解决此问题,请遵循约定并将 _id 附加到您的外键,即 delivery_address_idinvoice_address_id,或者使用更改 属性 名称propertyName 选项

$this->belongsTo('DeliveryAddresses', [
    'propertyName' => 'delivery_address_data',
    //...
]);

$this->belongsTo('InvoiceAddresses', [
    'propertyName' => 'invoice_address_data',
    //...
]);

除非您使用的是遗留数据库,否则我强烈建议您选择前一种解决方案并让您的外键遵循约定!