I have defined a users
table, a roles
table and a user_role
pivot in my database. The model for the user
is as follows:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
//... Fields defined here
public function roles()
{
return $this->belongsToMany(Role::class, 'user_role');
}
}
Inside the role model, I have this also:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
//... Fields defined here
public function users()
{
return $this->belongsToMany(User::class, 'user_role');
}
}
Now here lies the problem. When I run the following in the API routes (relatively crude)
$user_roles = \App\Models\User::with('roles')->get();
I get a list of all the users, with each array having an internal array of all the roles. I will like the results such that each user will have one role and if there are multiple roles, I duplicate the user with this new role.
How is this achieved? Thanks in advance for the assistance
CodePudding user response:
You can do something like flatMap
:
$user_roles = \App\Models\User::with('roles')->get()
->flatMap(function ($user) {
if ($user->roles->isEmpty()) { return $user; }
return $user->roles->map(function ($role) use ($user) {
$newUser = clone $user;
$newUser->roles = $role;
return $newUser;
});
});
An alternative is to use a join instead of an eloquent relationship e.g.:
$user_roles = DB::table('users')
->join('user_role', 'user_role.user_id', 'user.id')
->join('roles', 'user_role,role_id', 'roles.id')
->selectRaw('users.*, roles.*')->get();
This should result in a result of users and roles combined in one object.