Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

requincreative's avatar

Many to Many - Sync Issue

Hello

I am trying to build a role manager application where managers across different organizations (campuses) can assign a user to roles within their building while not affecting roles under different buildings

I have employee which should have the same roles in two different campuses with the data as follows.

id	user_id	role_id	Group	CampusCode	UserID	ModUser	created_at	updated_at	school_year
1368	30	5	CCMR	FSE-122	21191	23636	2022-08-26 06:42:09.453	2022-08-26 07:01:53.617	2023
1375	30	7	Counselor	FSE-122	21191	23636	2022-08-26 07:01:53.620	2022-08-26 07:01:53.620	2023
1376	30	8	Counselor-Lead	FSE-122	21191	23636	2022-08-26 07:01:53.627	2022-08-26 07:01:53.627	2023
1377	30	13	HomelessLiaison	FSE-122	21191	23636	2022-08-26 07:01:53.627	2022-08-26 07:01:53.627	2023

id	user_id	role_id	Group	CampusCode	UserID	ModUser	created_at	updated_at	school_year
1378	30	5	CCMR	LSE-113	21191	14869	2022-08-26 06:42:09.453	2022-08-26 07:01:53.617	2023
1379	30	7	Counselor	LSE-113	21191	14869	2022-08-26 07:01:53.620	2022-08-26 07:01:53.620	2023
1380	30	8	Counselor-Lead	LSE-113	21191	14869	2022-08-26 07:01:53.627	2022-08-26 07:01:53.627	2023
1381	30	13	HomelessLiaison	LSE-113	21191	14869	2022-08-26 07:01:53.627	2022-08-26 07:01:53.627	2023

But what happens is if one manager makes a change to the user roles for their campus it drops all of the roles at the other campus and replaces with newly assigned roles.

I have the following relationships set up in two models

User.php

 public function locker_roles()
    {
        return $this->belongsToMany('App\LockerRole', 'CRR_CampusRole_Assignments', 'user_id', 'role_id')
             ->withPivot('CampusCode', 'UserId', 'ModUser', 'school_year')
            ->withTimestamps();
    }
LockerRole.php
 public function users()
    {
        return $this->belongsToMany('App\User', 'CRR_CampusRole_Assignments', 'role_id', 'user_id')
            ->withPivot('CampusCode', 'UserId', 'ModUser', 'school_year')
            ->withTimestamps();
    }

Here is the controller method where I use the sync() method on the relationship

public function staff_update(Request $request, User $user)
    {

        $locker_arr = array();
        $utility = new Utility();
        $school_year = $utility->getSchoolYear();

        if (!empty($request->input('roles'))) {
            foreach ($request->input('roles') as $v) {

                $role = LockerRole::findOrFail($v);
   

                $locker_arr[$v] = array(
                    'Group' => $role->group_name,
                    'CampusCode' => auth()->user()->campus,  // Change this or not?
                    'UserID' => $user->ein,
                    'ModUser' => auth()->user()->ein,
                    'school_year' => $school_year
                );
            }
        }




        $sync = $user->locker_roles()->sync($locker_arr);  // is an array with attached, detached, updated

   

       

        return redirect()->back()->with('success', 'Roles updated for user successfully');
    }

Sadly this went to production some time ago without adequate testing and I am now eating crow for delivering something I didn't fully understand.

TIA

0 likes
1 reply
requincreative's avatar
requincreative
OP
Best Answer
Level 6

Adding a where query to the Pivot Column seems to be the solution for me.

->wherePivot('CampusCode', auth()->user()->campus)

$sync = $user->locker_roles()->wherePivot('CampusCode', auth()->user()->campus)->sync($locker_arr);  // is an array with attached, detached, updated

Please or to participate in this conversation.