CakePHP 3.日志含义X - patchEntity设置外键失败


CakePHP 3.X - patchEntity failed to set foreign key

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

订单与地址有2个关联(交货和发票)。

关联地址已经存在,所以我只想将地址id保存为Orders表中的外键。

OrdersTable

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"=比;空,

"invoice_address"=比;空,

当我删除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',
    //...
]);

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