I found an issue in my application where when a user registers, it doesn’t insert the firstname
and lastname
into the associated table.
This was “intended” behaviour (more like: I forgot to implement this) back then so I started to fix it.
Fast forward two days and I can’t get it to work.
This is what I want:
- Create a new user entity (for the username, email, password and creation date) for the
Users
(named users
in the db) table
- Add data to the associated
UsersDetails
(named users_details
in the db) table
- Save it all
- Check whether it went right (to show success message or error message as needed)
This is the code I have currently written for that:
$user = $this->Users->newEntity([
'username' => $this->request->getData('username'),
'email' => $this->request->getData('email'),
'password' => $this->request->getData('password'),
'created' => date("Y-m-d H:i:s"),
'users_details' => [
'firstname' => '',
'lastname' => ''
]
]);
if($this->Users->save($user)) {
...
The user is inserted into the Users
table but Cake seems to “ignore” the fact that I added stuff to the UsersDetails
table as well (so it doesn’t add a new entry to it).
This us my User
entity file:
class User extends Entity {
use UserTrait;
protected $_accessible = [
'username' => true,
'email' => true,
'password' => true,
'created' => true,
'articles' => true,
'roles' => true,
'users_details' => true
];
protected $_hidden = [
'password'
];
}
The UsersTable
has an association to the UsersDetails
table:
$this->hasOne('UsersDetails', [
'foreignKey' => 'id',
'joinType' => 'INNER'
]);
How can I make it work?
UPDATE: changed the belongsTo
to hasOne
rename users_details
to users_detail
as its belongsTo
https://book.cakephp.org/3.0/en/orm/saving-data.html#saving-belongsto-associations
When saving belongsTo associations, the ORM expects a single nested entity named with the singular
when in doubt how your post structure should looks like you can always get record first and take a peek
$user = $this->Users->findById(1)->contain(['UsersDetails'])->first();
dd($user);
Doing this results in the error:
The UsersDetails association is not defined on Users.
Last time I encountered this issue I forgot to load the model (which I did this time).
sounds like wrong namespace / filename / letter casing
<?php
namespace Kikioboeru\Kikioboeru\Model\Table;
class UsersDetailsTable extends Table {
...
Loaded in the controller with:
$this->loadModel('Kikioboeru/Kikioboeru.UsersDetails');
you are loading UsersDetails
and trying to use Users
table?
I also have the Users
Table loaded.
Like I said in the OP, I want to create a new user
entity for the username
, password
and email
and have associated data inserted into the UsersDetails
table (the firstname
and lastname
of the user)
So I have some progress.
$this->Users
has no associations at all (even though specified in the UsersTable
).
dd($this->Users);
results in:
Table {#239
+"registryAlias": "Users"
+"table": "users"
+"alias": "Users"
+"entityClass": "Cake\ORM\Entity"
+"associations": []
+"behaviors": []
+"defaultConnection": "default"
+"connectionName": "default"
}
however, TableRegistry::get('Kikioboeru/Kikioboeru.Users')
does have associations:
$usersTable = TableRegistry::get('Kikioboeru/Kikioboeru.Users');
dd($usersTable);
results in:
UsersTable {#272
+"registryAlias": "Kikioboeru/Kikioboeru.Users"
+"table": "users"
+"alias": "Users"
+"entityClass": "Kikioboeru\Kikioboeru\Model\Entity\User"
+"associations": array:3 [
0 => "articles"
1 => "roles"
2 => "usersdetails"
]
+"behaviors": array:1 [
0 => "Timestamp"
]
+"defaultConnection": "default"
+"connectionName": "default"
}
Is this a bug in CakePHP or?
For those wondering, this is my initialize
method:
public function initialize() {
parent::initialize();
$this->loadModel('Kikioboeru/Kikioboeru.Users');
$this->loadModel('Kikioboeru/Kikioboeru.UsersDetails');
$this->loadModel('Kikioboeru/Kikioboeru.ResetTokens');
$this->loadModel('Kikioboeru/Kikioboeru.AuthTokens');
}
Using the TableRegistry (instead of $this->Users
) as shown above does make the issue go away.
Could somebody explain me why, even though I loaded the model it uses a completely different model instead?
It seems to have used some build-in model(?) instead of the one I specified in my controller.
whats in parent::initialize()
? maybe you already have loaded Users
table before loading your plugin Users
table version
Can you can use setProperty (or propertyName in array) to the relation to try force the association to be saved?
How about
$userData =[
'username' => $this->request->getData('username'),
'email' => $this->request->getData('email'),
'password' => $this->request->getData('password'),
'created' => date("Y-m-d H:i:s"),
'users_details' => [
'firstname' => '',
'lastname' => ''
]
];
$user = $this->Users->newEntity($userData, [‘associated’ => ‘UserDetails’]);
pr($user);
There is one note of $this->loadModel('Users');
in the plugin’s AppController!
Unfortunately, I’ll have to try this out tomorrow when I have access to my workstation again.
Will report back!
Jepp, this seemed to be the issue…
I have updated the “rules” of the project to prevent these issues down the road.