cakephp 框架中可能存在错误,但不确定
我得到了以下 MySQL InnoDB 表:
database.users
+-----+---------------+----------+
| id | user_group_id | username |
+-----+---------------+----------+
| INT | INT | VARCHAR |
database.user_settings
+-----+---------------+----------+
| id | user_id | data |
+-----+---------------+----------+
| INT | INT | VARCHAR |
我在表类中得到了以下初始化:
$this->table('users');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('UserGroups', [
'foreignKey' => 'user_group_id'
]);
$this->hasOne('UserSettings', [
'foreignKey' => 'user_id'
]);
$this->table('user_settings');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('Users', [
'foreignKey' => 'user_id'
]);
// And folowing validation rules:
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create')
// UserSettings.user_id validation rule:
->add('user_id', 'valid', ['rule' => 'numeric'])
->requirePresence('user_id', 'create')
->notEmpty('user_id');
我得到了以下代码:
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data, [
'associated' => ['Users.UserSettings']
]);
// Tried it also this way, won't change anything
//$user = $this->Users->patchEntity($user, $this->request->data, [
// 'associated' => ['user_setting']
//]);
$this->Users->save($user,['associated' => ['UserSettings']]);
}
示例输入数据($this->request->data):
[
'user_group_id' => 1, // Not related to question
'username' => 'test', // This will be saved without core modifications
'user_setting' => [
'data' => 'sample data' // Saved only after "fix" described below
]
];
这将保存父表(users),但不会保存子表(user_settings)。
然后我得到了以下我想删除的修改:
如果我将此更改放入 ORM\Associations\HasOne::saveAssociated(...)
// $this->property() == 'user_setting'
if (is_array($targetEntity)) {
$targetEntity = $this->target()->newEntity($targetEntity);
}
它会立即按照我想要的方式工作。 HasOne 实际上具有所需的数据,但它还会检查数据是否在实体内部,在本例中它位于数组中。
我尝试过不同的关联命名组合,看起来应该是这样的。
主要问题是我应该如何保存可选的 hasOne 与父行的关联?
我可以以某种方式确保数据将转换为实体对象吗? 我认为它应该可以正常工作,因为所有必需的数据都可用,而且它似乎也可以正确处理关系。
最佳答案
在@ndm提供的帮助下,我设法使用自定义编码器解决了这个问题。
我首先确实查看了单独的验证器,但对我来说,解决非常简单直接的问题似乎过于复杂和脆弱。
我诚实的观点是,所有这些实际上都应该在框架核心内部以某种方式得到处理。
使用自定义编码器解决所需的 fk:
这样应该确保仅当通过用户创建 UserSettings 并且 user_settings.user_id 应随时可用时才会使用“自定义验证”。
class UsersMarshaller extends Marshaller {
protected function _validate($data, $options, $isNew) {
$errors = parent::_validate($data, $options, $isNew);
if ($isNew) {
unset($errors['user_setting']['user_id']['_required']);
}
return $errors;
}
}
在UsersTable
类中:
public function marshaller() {
return new UsersMarshaller($this);
}
原始问题中的实际错误:
patchEntity(...)
调用参数有错误,即使这些参数所做的事情使它们看起来可能是正确的。
关联应该是这样的:['linked' => ['UserSettings']]
。不是 Users.UserSettings
或 user_setting
。
关于php - CakePHP 3 保存 HasOne 关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28393995/