possible bug in cakephp framework but not sure about that
I got following MySQL InnoDB tables:
database.users
+-----+---------------+----------+
| id | user_group_id | username |
+-----+---------------+----------+
| INT | INT | VARCHAR |
database.user_settings
+-----+---------------+----------+
| id | user_id | data |
+-----+---------------+----------+
| INT | INT | VARCHAR |
I got following intialization in table classes:
$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');
And I got following code:
$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']]);
}
Sample input data ($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
]
];
This will save parent table (users) but not child table (user_settings).
Then I got following modification I want to get rid of:
If I put this change to ORM\Associations\HasOne::saveAssociated(...)
// $this->property() == 'user_setting'
if (is_array($targetEntity)) {
$targetEntity = $this->target()->newEntity($targetEntity);
}
It will instantly work the way I wanted to. HasOne actually has required data but it also checks if data is inside Entity, in this case it was in array.
I've played with different association naming combinations and it seems that this is how it should be.
Main question is how should I save optional hasOne association with parent row?
Can I somehow make sure that data will be converted into Entity object? I think it should just work as there is all required data available and it also seems to handle relations correctly.