current_workspace_id !== $workspace->id) { return; } $fallback = $user->workspaces() ->where('workspaces.id', '!=', $workspace->id) ->where('workspaces.account_id', $workspace->account_id) ->first(); if (! $fallback && $attachOwnerFallback) { $fallback = self::ownerAccountFallback($user, $workspace, $account); } $user->update(['current_workspace_id' => $fallback?->id]); } /** * Point every user whose current workspace is $workspace at another * same-account membership (or null). Used when the workspace is deleted. */ public static function awayFromWorkspace( Workspace $workspace, ?string $exceptUserId = null, bool $attachOwnerFallback = false, ?Account $account = null, ): void { User::query() ->where('current_workspace_id', $workspace->id) ->when( $exceptUserId, fn ($query) => $query->where('id', '!=', $exceptUserId), ) ->get() ->each(fn (User $user) => self::forUserAwayFrom( $user, $workspace, $attachOwnerFallback, $account, )); } private static function ownerAccountFallback( User $user, Workspace $deleting, ?Account $account, ): ?Workspace { // Use the already-loaded account owner_id — never isAccountOwner(), // which can touch the account relation under shouldBeStrict(). $isOwnerOfDeletingAccount = $account !== null && $user->id === $account->owner_id && $user->account_id === $deleting->account_id; if (! $isOwnerOfDeletingAccount) { return null; } $fallback = Workspace::query() ->where('account_id', $deleting->account_id) ->where('id', '!=', $deleting->id) ->first(); if ($fallback && ! $user->belongsToWorkspace($fallback)) { $fallback->members()->syncWithoutDetaching([ $user->id => ['role' => Role::Admin->value], ]); } return $fallback; } }