3

I have three arrays.

$data1 = []; $data2 =[]; $data3 = [];

foreach($request->clients as $client)
{
  $data1[]= [$client=>['role'=>'client']];
}

foreach($request->employees as $employee)
{
   $data2[]= [$employee=>['role'=>'employee']];
}

foreach($request->users as $user)
{
   $data3[] = [$user=>['role'=>'user']];
}

$data1 = [1=>['role'=>'client'], 2=>['role'=>'client']];
$data2 = [1=>['role'=>'employee']];
$data3 = [1=>['role'=>'user']];

//merge or recursive merge or... $data1, $data2, $data3.

$result = [1=>['role'=>'client'], 2=>['role'=>'user'], 1=>['role'=>'user'], 1=>['role'=>'employee']];

How can I get result like above? This is for Laravel Many to Many Sync with additional column.

Thanks

LoveCoding
  • 1,121
  • 2
  • 12
  • 33

1 Answers1

1

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)
}
Kurt Friars
  • 3,625
  • 2
  • 16
  • 29