record->name.' (ID: '.$this->record->id.')'; } public function getHeaderActions(): array { return [ \Filament\Actions\Action::make('Save')->action('save'), ViewAction::make(), DeleteAction::make(), ]; } public function mutateFormDataBeforeFill(array $data): array { $permissions = DB::select('SELECT permission_id FROM role_has_permissions WHERE role_id = '.$this->record?->id); $this->permissionsArray = $permissions; $data = array_merge($data, [ 'permissions' => array_column($permissions, 'permission_id', 'permission_id'), ]); return $data; } protected function mutateFormDataBeforeSave(array $data): array { // Check if 'permissions' key exists in the data array if (array_key_exists('permissions', $data)) { // Remove the 'permissions' array from the data that will be // passed to the Role model's fill() method. // The actual permission syncing will be handled in the custom save() method. unset($data['permissions']); } return $data; // Return the modified data array } // Your existing public function save within the EditRole page class: public function save(bool $shouldRedirect = true, bool $shouldSendSavedNotification = true): void { // It's crucial to get the full form state (including permissions) *before* // parent::save() is called, as parent::save() will use the data // mutated by mutateFormDataBeforeSave (which excludes 'permissions'). $fullFormState = $this->form->getState(); try { // parent::save() will now operate on data that has had 'permissions' removed // by the mutateFormDataBeforeSave hook. // $this->record will be updated with the saved/updated role instance. $this->record->update([ 'id' => $this->record->id, 'name' => data_get($fullFormState, 'name'), 'team_id' => data_get($fullFormState, 'team_id', null), ]); } catch (\Throwable $e) { Notification::make('error') ->title('An error occurred while saving the role') ->body('The error was: '.$e->getMessage()) ->danger() ->send(); return; } // After the role is successfully saved, proceed with permission syncing. // Use the $fullFormState captured before parent::save. $permissionsInput = Arr::get($fullFormState, 'permissions'); // This can be an array or null // Ensure we have a valid record (the role that was just saved) and its ID. if ($this->record && $this->record->id) { $grantedPermissionIds = []; // Check if $permissionsInput is an array and not empty. // The keys of $permissionsInput are permission IDs, and values are booleans. if (is_array($permissionsInput) && ! empty($permissionsInput)) { foreach ($permissionsInput as $permissionId => $isChecked) { if ($isChecked && $permissionId) { // Ensure $isChecked is true and $permissionId is valid $grantedPermissionIds[] = $permissionId; } } } // If $grantedPermissionIds is empty (no permissions selected or $permissionsInput was null/empty), // syncPermissions([]) will detach all existing permissions from the role. $this->record->syncPermissions($grantedPermissionIds); } Notification::make('success') ->title('Saved') ->success() ->send(); } }