After discussion with OP, the structure, needed to be changed to allow for the relationships role to be able to associate with many roles. To achieve this, we can do as follows.
Schema:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
});
Schema::create('teams', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
});
Schema::create('memberships', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('team_id');
// Any other data you want here is fine
});
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
});
Schema::create('membership_role', function (Blueprint $table) {
$table->unsignedBigInteger('membership_id');
$table->unsignedBigInteger('role_id');
});
Now for Membership.php
class Membership extends Model
{
public static function create(User $user, Team $team, array $roles = [])
{
$membership = new self();
$membership->user_id = $user->id;
$membership->team_id = $team->id;
$membership->save();
$attach = [];
foreach ($roles as $role) {
$attach[] = Role::resolveId($role);
}
$membership->roles()->attach($attach);
return $membership;
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function syncRoles(array $roles)
{
$sync = [];
foreach ($roles as $role) {
$sync[] = Role::resolveId($role);
}
$this->roles()->sync($sync);
}
}
And Role.php
class Role extends Model
{
const CLIENT = 'client';
const EMPLOYEE = 'employee';
const USER = 'user';
public function memberships()
{
return $this->belongsToMany(Membership::class);
}
public static function resolveId()
{
if (is_int($role)) {
return $role;
}
if (is_string($role)) {
$role = Role::where('name', $role)->first();
}
return $role->id;
}
}
Now you can assume the other classes are implemented with the obvious relations and do:
foreach($request->clients as $client)
{
if (!isset($roleSync[$client])) {
$roleSync[$client] = [];
}
$roleSync[$client][] = Role::CLIENT;
}
foreach($request->employees as $employee)
{
if (!isset($roleSync[$employee])) {
$roleSync[$employee] = [];
}
$roleSync[$employee][] = Role::EMPLOYEE;
}
foreach($request->users as $user)
{
if (!isset($roleSync[$user])) {
$roleSync[$user] = [];
}
$roleSync[$user][] = Role::USER;
}
$ids = array_keys($roleSync);
$users = User::with('membership.roles')
->whereIn('id', $ids)
->get();
foreach ($users as $user) {
$roles = $roleSync[$user->id];
$user->membership->syncRoles($roles)
}