I’m trying to import users and data into my app.
The data for a user is build and saved like this:
$data = [
'id' => $user['ID'],
'username' => $user['user_nicename'],
'email' => $user['user_email'],
'password' => $user['user_pass'],
'created' => $user['user_registered'],
'users_detail' => [
'firstname' => $user['user_nicename'],
'lastname' => ''
'roles' => [
['id' => $memberRole->id]
$usersEntity = $usersTable->newEntity($data);
The user is inserted just fine except with one issue: the
id is just plainly ignored and keeps following the
autoincrement from the database.
Is there a way to insert the user with the proper ID?
Just rolling with it like this will complicate matters a lot as now the data from the other tables I need to migrate won’t align with the users at all (eg. the user with
id=3 in the database actually is known with
id=9, the one with
id=4 in the database actually is known with
$usersEntity->id = $user['ID']; before saving it does the trick
The default code baked for you will exclude the primary key from being assigned in a patch call. Look at the
_accessible property in your entity. There’s good security reasons to leave it like that most of the time; see Bypassing Field Guarding for a solution that might work well for your use case.
This might be a cleaner way of doing it yes
I’ll test it out when I’m back at the office tomorrow.
Seems to work fine as well
A word of warning if you allow the ID column to be mass assigned… If you have an action: ‘add’ controller/view that has the ID as a text input, and you submit the form with the same ID as an existing record in your table - that record will be overwritten without warning.
The approach I use now is the same as your first answer…
$entity->id = $data[‘id’];
However, I run a select to check for an existing record with the same ID forst in my controller - which allows my to return a validation error.
Just for context, my use case was dealing with Products (like ecommerce), and the Product SKU is a natural key usually, so I wanted to SKU to be the entity ID.
This is why you’d want to leave the
_accessible property set as it is by default, and use the one-time bypass method from my link only in specific cases like the OP has, where the data is all built from a trusted source.
Yea, it’s only a “one-time” thing because I had to import data (like users, blogposts, comments etc.) from my live website into my CakePHP app