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

sshateri's avatar

sync() adds roles but doesnt remove them

i have been pulling my hair for hours now yet still don't understand why my code adds roles to the user but doesn't remove them.

component

<?php

namespace App\Http\Livewire\Admin;

use App\Models\Role;
use App\Models\User;
use Livewire\Component;

class EditUser extends Component
{
    public $user;
    public $roles;
    public $userName;
    public $userEmail;
    public $userRoles = [];

    public function render()
    {
        return view('livewire.admin.edit-user')
            ->layout('layouts.admin.app');
    }

    public function getRoles()
    {
        $this->roles = Role::all();
    }

    public function mount(User $user)
    {
        $this->getRoles();
        $this->user = $user;
        $this->userName = $user->name;
        $this->userEmail = $user->email;
        $this->userRoles = $user->roles->pluck('id');
    }

    public function updateUser()
    {
        $this->user->update([
            'name' => $this->userName,
            'email' => $this->userEmail,
        ]);

        $this->user->roles()->sync($this->userRoles);

        redirect()->route('admin.users');
    }


}

blade view

<form dir="ltr" wire:submit.prevent="updateUser">
    <h2 class="text-gray-900 text-lg font-medium title-font mb-5">Edit User</h2>
    <div class="relative mb-4">
        <label for="full-name" class="leading-7 text-sm text-gray-600">Full Name</label>
        <input wire:model.defer="userName" type="text" id="full-name" name="name"
            class="w-full bg-white rounded border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-300 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out">
    </div>

    <div class="relative mb-4">
        <label for="email" class="leading-7 text-sm text-gray-600">Email</label>
        <input wire:model.defer="userEmail" type="email" id="email" name="email"
            class="w-full bg-white rounded border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-300 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out">
    </div>

    <div class="relative mb-4">
        <div class="flex flex-row items-center">
            @foreach ($roles as $role)
            <div class="flex flex-col mr-3">
                <label class="inline-flex items-center mt-3" for="{{ $role->name }}">
                    <input wire:model.defer="userRoles" type="checkbox" name="{{ $role->name }}" value="{{ $role->id }}"
                        id="{{ $role->name }}"
                        class="form-checkbox h-5 w-5 text-blue-500 rounded border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-300 outline-none transition-colors duration-200 ease-in-out"
                        {{-- @if (in_array($role->id , $userRoles->toArray())) checked @endif --}}><span
                        class="ml-2 leading-7 text-sm text-gray-600">{{ $role->name }}</span>
                </label>
            </div>
            @endforeach
        </div>
    </div>

    <button wire.click="updateUser"
        class="flex text-white bg-blue-500 transition-colors duration-150 ease-linear border-0 py-2 px-8 focus:outline-none hover:bg-blue-400 rounded text-lg mt-10 sm:mt-0 font-medium items-center">
        <svg role="status" aria-hidden="true" wire:loading wire:target="updateUser"
            class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
            viewBox="0 0 24 24">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
            <path class="opacity-75" fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
            </path>
        </svg>
        <span class="">Update</span>
    </button>
    {{-- <p class="text-xs text-gray-500 mt-3">Literally you probably haven't heard of them jean shorts.</p> --}}
    <div class="relative mt-4 text-right" dir="rtl">
        @error('name')
        <small class="text-red-500 ml-3">{{ $message }}</small>
        @enderror
        @error('email')
        <small class="text-red-500 ml-3">{{ $message }}</small>
        @enderror

    </div>

</form>
0 likes
7 replies
sshateri's avatar

@webrobert thanks for the reply but that doesn't seem to be what's happening to me because it adds the correct value to the array not the true or false and in fact it adds the coorect roles using sync and the dd shows the correct values in the array but just when I unckeck a role it doesn't remove the corresponding value from the array and just sends the old ones which are already assigned to the user.

webrobert's avatar

@sshateri,

When I dd you code.. I get this when selecting...

array:8 [▼
  0 => 13
  1 => 11
  2 => 3
  3 => 12
  4 => 7
  5 => 8
  6 => "10"
  7 => "9"
]

string values for the selected items

webrobert's avatar

@sshateri or... maybe this...

   $this->user->roles()->sync( 
		array_map('intval', $this->userRoles)
   );
sshateri's avatar

@webrobert thats right it works but i still can't understand why my code doesn't work and that is frustrating.

Please or to participate in this conversation.