Your code snipplet is confusing, could you show the original data from $request->all() and give an example of how you want it inserted
Jul 20, 2021
3
Level 5
Guidance With using UPSERT
I have a question how would I format UPSERT to insert into 3 tables from each row coming from external post request with the following example.
collect($request->all())
->map(function (array $row) {
return Arr::only($row,
[
'email' => $row['email'],
'name' => $row['name'],
'address' => $row['address'],
],
[
'role' => $row['role'],
],
[ // need some way to foreach or something here
name => $row['name'],
name => $row['name'],
name => $row['name'],
]
)
})
->chunk(100)
->each(function (Collection $chunk) {
Contact::upsert($chunk, 'email');
Role::upsert($chunk, 'role');
Permission::upsert($chunk, 'name');
});
Level 1
Thanks.
A good rule of thumb when attempting to try something new is to
- Make it work
- Optimize if needed for readability and or speed.
After I created the code example I realized your user "hasMany" permissions and not "belongsToMany", which causes this code to not work, you would need to change the relationship to a "belongsToMany" relationship, the docs has great documentation for this.
collect($request->all())
->each(function ($row) {
collect($row['data'])->each(function ($row) {
/*
* Convert array to collection
*/
$row = collect($row);
/*
* Create user if needed (the email field is determined to see if the user exists or not)
*/
$user = \App\Models\User::firstOrCreate(
$row->only('email'),
$row->only(['published', 'name', 'address'])
);
/*
* Here we do the same thing for the Role
*/
$role = \App\Models\Role::firstOrCreate($row->only(['role']));
/*
* "permissions" => array:1 [
* 0 => "can_access,can_edit"
* ]
*/
$permissionIds = collect($row->get('permissions'))->map(function ($permissionStr) {
// $permissionStr is "can_access,can_edit" etc
$ids = [];
// explode string
$permissionArr = explode(',', $permissionStr);
// Create each access property and return it
foreach ($permissionArr as $name) {
$ids[] = \App\Models\Permission::firstOrCreate(['name' => $name])->id;
}
return $ids;
})
->flatten(1) // because this array will be nested we have to flatten it. AKA [[1,2], [1,2]] => [1,2,1,2]
->unique(); // remove duplicates. AKA [1,2,1,2] => [1,2]
/*
* Set the role id and save the model
*/
$user->role_id = $role->id;
$user->save();
/*
* Attach permissions by ID
*/
$user->Permissions()->sync($permissionIds);
/*
* We are now done!
*/
});
});
Please or to participate in this conversation.