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

doniaries's avatar

Column 'id' in where clause is ambiguous

I have an error SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous

please help me with the solution, thank you

this my code : on user resource ->modifyQueryUsing(function (Builder $query) { // Perhatikan penggunaan users.id untuk menghindari ambiguitas $query->where('users.id', '!=', auth()->id());

            // Jika bukan super_admin, filter berdasarkan team dan jangan tampilkan super_admin
            if (!auth()->user()->hasRole('super_admin')) {
                $teamIds = auth()->user()->teams->pluck('id')->toArray();
                $query->whereHas('teams', function ($q) use ($teamIds) {
                    $q->whereIn('teams.id', $teamIds);
                })
                    ->whereDoesntHave('roles', function ($q) {
                        $q->where('name', 'super_admin');
                    });
            }
        });

public static function getEloquentQuery(): Builder { $query = parent::getEloquentQuery();

    // Super admin bisa lihat semua user
    if (auth()->user()->hasRole('super_admin')) {
        return $query;
    }

    // Admin OPD hanya bisa lihat user di teamnya
    $teamIds = auth()->user()->teams->pluck('id')->toArray();

    return $query
        ->whereHas('teams', function ($query) use ($teamIds) {
            $query->whereIn('teams.id', $teamIds);
        })
        ->whereDoesntHave('roles', function ($query) {
            $query->where('name', 'super_admin');
        });
}

I use the plugin shield and my app multi tenancy

0 likes
13 replies
doniaries's avatar

SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous select teams.*, team_user.user_id as pivot_user_id, team_user.team_id as pivot_team_id from teams inner join team_user on teams.id = team_user.team_id where team_user.user_id = 2 and id in (1)

I asked Ai, the answer was in the problem in method getEloquentQuery, I've applied it, it doesn't work either

JussiMannisto's avatar

That's the error message you get from the database. Which line of code does it come from? The file and line are shown on the error page and the log file (storage/logs/laravel.log by default).

The error here is that your SQL query has the condition ... and id in (1), but the query has two id columns: teams.id and team_user.id. The database doesn't know which one to use.

You didn't show the part where the query is executed.

doniaries's avatar

@JussiMannisto Sorry, I'm a beginner, this is the error log [previous exception] [object] (PDOException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous at C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Connection.php:423) [stacktrace] #0 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Connection.php(423): PDO->prepare('select teams....') #1 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Connection.php(816): Illuminate\Database\Connection->Illuminate\Database\{closure}('select teams....', Array) #2 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Connection.php(783): Illuminate\Database\Connection->runQueryCallback('select teams....', Array, Object(Closure)) #3 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Connection.php(414): Illuminate\Database\Connection->run('select teams....', Array, Object(Closure)) #4 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php(2913): Illuminate\Database\Connection->select('select teams....', Array, true) #5 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php(2902): Illuminate\Database\Query\Builder->runSelect() #6 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php(3456): Illuminate\Database\Query\Builder->Illuminate\Database\Query\{closure}() #7 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php(2901): Illuminate\Database\Query\Builder->onceWithColumns(Array, Object(Closure)) #8 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php(739): Illuminate\Database\Query\Builder->get(Array) #9 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Relations\BelongsToMany.php(874): Illuminate\Database\Eloquent\Builder->getModels() #10 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Relations\BelongsToMany.php(853): Illuminate\Database\Eloquent\Relations\BelongsToMany->get() #11 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Components\Select.php(830): Illuminate\Database\Eloquent\Relations\BelongsToMany->getResults() #12 C:\laragon\www\e-surat-shield-team\vendor\filament\support\src\Concerns\EvaluatesClosures.php(35): Filament\Forms\Components\Select::Filament\Forms\Components\{closure}(Object(Filament\Forms\Components\Select), NULL) #13 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Components\Concerns\BelongsToModel.php(87): Filament\Support\Components\Component->evaluate(Object(Closure)) #14 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Components\Concerns\HasState.php(240): Filament\Forms\Components\Component->loadStateFromRelationships() #15 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Components\Select.php(1254): Filament\Forms\Components\Component->hydrateDefaultState(NULL) #16 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Components\Concerns\HasState.php(216): Filament\Forms\Components\Select->hydrateDefaultState(NULL) #17 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Concerns\HasState.php(203): Filament\Forms\Components\Component->hydrateState(NULL, true) #18 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Components\Concerns\HasState.php(219): Filament\Forms\ComponentContainer->hydrateState(NULL, true) #19 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Concerns\HasState.php(203): Filament\Forms\Components\Component->hydrateState(NULL, true) #20 C:\laragon\www\e-surat-shield-team\vendor\filament\forms\src\Concerns\HasState.php(188): Filament\Forms\ComponentContainer->hydrateState(NULL, true) #21 C:\laragon\www\e-surat-shield-team\vendor\filament\actions\src\Concerns\CanBeMounted.php(34): Filament\Forms\ComponentContainer->fill(Array) #22 C:\laragon\www\e-surat-shield-team\vendor\filament\support\src\Concerns\EvaluatesClosures.php(35): Filament\Actions\MountableAction->Filament\Actions\Concerns\{closure}(Object(Filament\Forms\Form)) #23 C:\laragon\www\e-surat-shield-team\vendor\filament\actions\src\Concerns\CanBeMounted.php(18): Filament\Support\Components\Component->evaluate(Object(Closure), Array) #24 C:\laragon\www\e-surat-shield-team\vendor\filament\tables\src\Concerns\HasActions.php(210): Filament\Actions\MountableAction->mount(Array) #25 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(36): Filament\Resources\Pages\ListRecords->mountTableAction('edit', '2', Array) #26 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Container\Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() #27 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure)) #28 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure)) #29 C:\laragon\www\e-surat-shield-team\vendor\livewire\livewire\src\Wrapped.php(23): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array) #30 C:\laragon\www\e-surat-shield-team\vendor\livewire\livewire\src\Mechanisms\HandleComponents\HandleComponents.php(474): Livewire\Wrapped->__call('mountTableActio...', Array) #31 C:\laragon\www\e-surat-shield-team\vendor\livewire\livewire\src\Mechanisms\HandleComponents\HandleComponents.php(101): Livewire\Mechanisms\HandleComponents\HandleComponents->callMethods(Object(App\Filament\Resources\UserResource\Pages\ListUsers), Array, Object(Livewire\Mechanisms\HandleComponents\ComponentContext)) #32 C:\laragon\www\e-surat-shield-team\vendor\livewire\livewire\src\LivewireManager.php(97): Livewire\Mechanisms\HandleComponents\HandleComponents->update(Array, Array, Array) #33 C:\laragon\www\e-surat-shield-team\vendor\livewire\livewire\src\Mechanisms\HandleRequests\HandleRequests.php(94): Livewire\LivewireManager->update(Array, Array, Array) #34 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php(46): Livewire\Mechanisms\HandleRequests\HandleRequests->handleUpdate() #35 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Route.php(259): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Livewire\Mechanisms\HandleRequests\HandleRequests), 'handleUpdate') #36 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Route.php(205): Illuminate\Routing\Route->runController() #37 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Router.php(806): Illuminate\Routing\Route->run() #38 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(144): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) #39 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #40 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure)) #41 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #42 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure)) #43 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #44 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure)) #45 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #46 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest(Object(Illuminate\Http\Request), Object(Illuminate\Session\Store), Object(Closure)) #47 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure)) #48 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #49 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure)) #50 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #51 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure)) #52 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #53 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Router.php(805): Illuminate\Pipeline\Pipeline->then(Object(Closure)) #54 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Router.php(784): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request)) #55 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Router.php(748): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route)) #56 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Routing\Router.php(737): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request)) #57 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(200): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request)) #58 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(144): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request)) #59 C:\laragon\www\e-surat-shield-team\vendor\livewire\livewire\src\Features\SupportDisablingBackButtonCache\DisableBackButtonCacheMiddleware.php(19): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #60 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Livewire\Features\SupportDisablingBackButtonCache\DisableBackButtonCacheMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure)) #61 C:\laragon\www\e-surat-shield-team\vendor\barryvdh\laravel-debugbar\src\Middleware\InjectDebugbar.php(66): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #62 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Barryvdh\Debugbar\Middleware\InjectDebugbar->handle(Object(Illuminate\Http\Request), Object(Closure)) #63 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #64 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure)) #65 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TrimStrings.php(36): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #66 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Foundation\Http\Middleware\TrimStrings->handle(Object(Illuminate\Http\Request), Object(Closure)) #67 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #68 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure)) #69 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance.php(99): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #70 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure)) #71 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Http\Middleware\HandleCors.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #72 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Http\Middleware\HandleCors->handle(Object(Illuminate\Http\Request), Object(Closure)) #73 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Http\Middleware\TrustProxies.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #74 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Illuminate\Http\Middleware\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure)) #75 C:\laragon\www\e-surat-shield-team\vendor\bilfeldt\laravel-route-statistics\src\Http\Middleware\RouteStatisticsMiddleware.php(22): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #76 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(183): Bilfeldt\LaravelRouteStatistics\Http\Middleware\RouteStatisticsMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure)) #77 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #78 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(175): Illuminate\Pipeline\Pipeline->then(Object(Closure)) #79 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(144): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request)) #80 C:\laragon\www\e-surat-shield-team\public\index.php(51): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request)) #81 C:\laragon\www\e-surat-shield-team\vendor\laravel\framework\src\Illuminate\Foundation\resources\server.php(16): require_once('C:\\laragon\\www\\...') #82 {main}

doniaries's avatar

this my resource <?php

namespace App\Filament\Resources;

use Filament\Forms; use App\Models\Team; use App\Models\Unit; use App\Models\User; use Filament\Tables; use App\Models\Jabatan; use Filament\Forms\Get; use Filament\Forms\Form; use Filament\Tables\Table; use Illuminate\Support\Str; use Filament\Facades\Filament; use Filament\Resources\Resource; use Filament\Support\Colors\Color; use Illuminate\Support\Facades\Hash; use Illuminate\Database\Eloquent\Model; use Filament\Notifications\Notification; use Illuminate\Database\Eloquent\Builder; use Illuminate\Validation\Rules\Password; use App\Filament\Resources\UserResource\Pages; use STS\FilamentImpersonate\Tables\Actions\Impersonate;

class UserResource extends Resource { protected static ?string $model = User::class;

protected static ?string $navigationIcon = 'heroicon-o-lock-closed';
protected static ?string $navigationLabel = 'Pengguna';

public static function shouldRegister(): bool
{
    return auth()->user()?->hasAnyRole(['super_admin', 'admin_opd']) ?? false;
}

public static function getNavigationGroup(): ?string
{
    return 'OPD';
}

public static function getNavigationSort(): ?int
{
    return 1;
}

public static function isScopedToTenant(): bool
{
    if (Filament::getTenant()->id === 1) {
        return false;
    }
    return true;
}

public static function form(Form $form): Form
{
    return $form
        ->schema([
            // Informasi Pribadi
            Forms\Components\Section::make('Informasi Pribadi')
                ->icon('heroicon-m-users')
                ->description('Data identitas pengguna')
                ->schema([
                    Forms\Components\TextInput::make('name')
                        ->label('Nama Lengkap')
                        ->prefixIcon('heroicon-m-user')
                        ->placeholder('Nama Lengkap')
                        ->unique(ignoreRecord: true)
                        ->required()
                        ->maxLength(255),
                    Forms\Components\TextInput::make('nip')
                        ->prefixIcon('heroicon-o-numbered-list')
                        ->label('NIP')
                        ->placeholder('Nomor Induk Pegawai')
                        ->default(null)
                        ->numeric()
                        ->unique(ignoreRecord: true)
                        ->maxLength(255),
                    Forms\Components\Select::make('teams')
                        ->label('OPD')
                        ->prefixIcon('heroicon-o-building-office')
                        ->relationship('teams', 'name', function ($query) {
                            if (auth()->user()->hasRole('super_admin')) {
                                return $query;
                            }
                            return $query->whereIn('id', auth()->user()->teams->pluck('id'));
                        })
                        ->createOptionForm([
                            Forms\Components\TextInput::make('name')
                                ->live(onBlur: true)
                                ->afterStateUpdated(fn($set, ?string $state) => $set('slug', Str::slug($state)))
                                ->required(),
                            Forms\Components\TextInput::make('slug')
                                ->disabled()
                                ->dehydrated()
                                ->required(),
                        ])
                        ->multiple()
                        ->preload()
                        ->searchable()
                        ->required()
                        ->live()
                        ->afterStateUpdated(function ($state, $set) {
                            $set('unit_id', null); // Reset unit_id ketika teams berubah
                            $set('jabatan_id', null); // Reset jabatan_id ketika teams berubah
                        }),

                    // Perbaikan: Untuk form select Unit, pastikan display title adalah 'nama_unit'
                    Forms\Components\Select::make('unit_id')
                        ->prefixIcon('heroicon-o-briefcase')
                        ->label('Unit/Bidang')
                        ->relationship(
                            name: 'unit',
                            titleAttribute: 'nama_unit',
                            modifyQueryUsing: function (Builder $query, Get $get) {
                                $selectedTeams = $get('teams');
                                return $query->when(
                                    $selectedTeams,
                                    fn($q) => $q->whereIn('team_id', $selectedTeams)
                                )->when(
                                    !auth()->user()->hasRole('super_admin') && empty($selectedTeams),
                                    fn($q) => $q->where('team_id', auth()->user()->teams()->first()?->id)
                                );
                            }
                        )
                        ->required()
                        ->createOptionForm([
                            Forms\Components\Hidden::make('team_id')
                                ->default(fn(Get $get) => $get('teams')[0] ?? auth()->user()->teams()->first()?->id),
                            Forms\Components\TextInput::make('nama_unit')
                                ->label('Nama Unit')
                                ->required()
                                ->unique(ignoreRecord: true)
                                ->maxLength(255)
                        ])
                        ->getOptionLabelFromRecordUsing(fn(Model $record): string => $record->nama_unit)
                        ->live()
                        ->afterStateUpdated(fn($set) => $set('jabatan_id', null))
                        ->searchable()
                        ->preload(),

                    Forms\Components\Select::make('jabatan_id')
                        ->prefixIcon('heroicon-o-briefcase')
                        ->label('Jabatan')
                        ->relationship(
                            name: 'jabatan',
                            titleAttribute: 'nama',
                            modifyQueryUsing: function (Builder $query, Get $get) {
                                $selectedTeams = $get('teams');
                                return $query->when(
                                    $selectedTeams,
                                    fn($q) => $q->whereIn('team_id', $selectedTeams)
                                )->when(
                                    !auth()->user()->hasRole('super_admin') && empty($selectedTeams),
                                    fn($q) => $q->where('team_id', auth()->user()->teams()->first()?->id)
                                );
                            }
                        )
                        ->required()
                        ->createOptionForm([
                            Forms\Components\Hidden::make('team_id')
                                ->default(fn(Get $get) => $get('teams')[0] ?? auth()->user()->teams()->first()?->id),
                            Forms\Components\TextInput::make('nama')
                                ->label('Nama Jabatan')
                                ->required()
                                ->unique('jabatan', 'nama', ignoreRecord: true)
                                ->maxLength(255)
                        ])
                        ->getOptionLabelFromRecordUsing(fn(Model $record): string => $record->nama)
                        ->live()
                        ->searchable()
                        ->preload(),
                ])->columns(2),

            // Informasi Akun
            Forms\Components\Section::make('Informasi Akun')
                ->description('Pengaturan akun dan hak akses')
                ->schema([
                    Forms\Components\TextInput::make('email')
                        ->label('Email')
                        ->prefixIcon('heroicon-o-at-symbol')
                        ->email()
                        ->placeholder('Masukkan alamat email')
                        ->required()
                        ->unique(ignoreRecord: true)
                        ->maxLength(255),
                    Forms\Components\TextInput::make('password')
                        ->label('Password')
                        ->revealable()
                        ->prefixIcon('heroicon-o-lock-closed')
                        ->password()
                        ->dehydrated(fn($state) => filled($state))
                        ->required(fn(string $context): bool => $context === 'create')
                        ->maxLength(255),
                    Forms\Components\Select::make('roles')
                        ->prefixIcon('heroicon-o-bolt')
                        ->label('Role')
                        ->relationship('roles', 'name', function ($query) {
                            if (auth()->user()->hasRole('super_admin')) {
                                return $query;
                            }
                            return $query->where('name', 'pegawai');
                        })
                        ->multiple()
                        ->preload()
                        ->searchable()
                        ->visible(fn() => auth()->user()->hasRole(['super_admin', 'admin_opd'])),
                    Forms\Components\Toggle::make('is_active')
                        ->label('Status Aktif')
                        ->onIcon('heroicon-m-bolt')
                        ->offIcon('heroicon-m-user')
                        ->onColor('success')
                        ->offColor('danger')
                        ->inline(false)
                        ->default(true),
                ])->columns(3),
        ]);
}

public static function table(Table $table): Table
{
    return $table
        ->query(static::getEloquentQuery())
        ->columns([
            Tables\Columns\TextColumn::make('email')
                ->badge()
                ->colors(['warning'])
                ->copyable()
                ->searchable(),
            Tables\Columns\TextColumn::make('name')
                ->label('Nama')
                ->searchable()
                ->sortable(),
            Tables\Columns\TextColumn::make('nip')
                ->label('NIP')
                ->searchable()
                ->sortable(),
            Tables\Columns\TextColumn::make('unit.nama_unit')
                ->color(fn($record) => collect([
                    Color::Amber,
                    Color::Sky,
                    Color::Emerald,
                    Color::Purple,
                    Color::Rose,
                    Color::Blue,
                    Color::Orange,
                    Color::Teal,
                    Color::Indigo,
                    Color::Yellow,
                ])->get($record->unit_id % 10 ?? 0))
                ->label('Unit/Bidang'),
            Tables\Columns\TextColumn::make('jabatan.nama')
                ->color(fn($record) => collect([
                    Color::Amber,
                    Color::Sky,
                    Color::Emerald,
                    Color::Purple,
                    Color::Rose,
                    Color::Blue,
                    Color::Orange,
                    Color::Teal,
                    Color::Indigo,
                    Color::Yellow,
                ])->get($record->jabatan_id % 10 ?? 0))
                ->label('Jabatan'),
            Tables\Columns\TextColumn::make('roles.name')
                ->badge()
                ->label('Role')
                ->colors(['primary']),
            Tables\Columns\TextColumn::make('teams.name')
                ->badge()
                ->colors(['success'])
                ->label('OPD'),
            Tables\Columns\ToggleColumn::make('is_active')
                ->label('Status User')
                ->action(function ($record, $column) {
                    if (!auth()->user()->hasRole(['super_admin'])) {
                        Notification::make()
                            ->title("Hanya Super Admin yang dapat mengubah status user")
                            ->danger()
                            ->send();
                        return;
                    }

                    $name = $record->name;
                    $record->update(['is_active' => !$record->is_active]);
                    Notification::make()
                        ->title($record->is_active ? "User $name telah diaktifkan" : "User $name telah dinonaktifkan")
                        ->success()
                        ->send();
                })
                ->visible(fn() => auth()->user()->hasAnyRole(['super_admin', 'admin_opd'])),
            Tables\Columns\TextColumn::make('created_at')
                ->label('Dibuat')
                ->dateTime('d M Y H:i')
                ->sortable()
                ->toggleable(isToggledHiddenByDefault: true),
            Tables\Columns\TextColumn::make('updated_at')
                ->label('Terakhir Update')
                ->dateTime('d M Y H:i')
                ->sortable()
                ->toggleable(isToggledHiddenByDefault: true),
        ])
        ->defaultSort('created_at', 'desc')
        ->filters([
            //
        ])
        ->actions([
            Tables\Actions\Action::make('Change Password')
                ->authorize('update')
                ->label('Ganti Password')
                ->icon('heroicon-o-key')
                ->form([
                    Forms\Components\TextInput::make('password')
                        ->required()
                        ->revealable()
                        ->password()
                        ->rule(Password::default())
                        ->same('passwordConfirmation'),
                    Forms\Components\TextInput::make('passwordConfirmation')
                        ->required()
                        ->revealable()
                        ->password(),
                ])
                ->action(function (User $user, array $data) {
                    $user->update(['password' => Hash::make($data['password'])]);

                    Notification::make()
                        ->success()
                        ->title('Password Sukses Diganti')
                        ->send();
                }),
            Impersonate::make(),
            Tables\Actions\EditAction::make()
                ->closeModalByClickingAway(false)
                ->stickyModalFooter()
                ->stickyModalHeader(),
            Tables\Actions\DeleteAction::make(),
        ])
        ->modifyQueryUsing(function (Builder $query) {
            // Perhatikan penggunaan users.id untuk menghindari ambiguitas
            $query->where('users.id', '!=', auth()->id());

            // Jika bukan super_admin, filter berdasarkan team dan jangan tampilkan super_admin
            if (!auth()->user()->hasRole('super_admin')) {
                $teamIds = auth()->user()->teams->pluck('id')->toArray();
                $query->whereHas('teams', function ($q) use ($teamIds) {
                    $q->whereIn('teams.id', $teamIds);
                })
                    ->whereDoesntHave('roles', function ($q) {
                        $q->where('name', 'super_admin');
                    });
            }
        });
}

public static function getRelations(): array
{
    return [];
}

public static function getPages(): array
{
    return [
        'index' => Pages\ListUsers::route('/'),
    ];
}

public static function getNavigationBadge(): ?string
{
    return cache()->remember('user_count_' . auth()->id(), 300, function () {
        $query = static::getEloquentQuery();

        if (auth()->user()->hasRole('super_admin')) {
            return $query->count();
        }

        // Menggunakan whereHas untuk filter berdasarkan relasi teams
        return $query->whereHas('teams', function ($q) {
            $q->whereIn('teams.id', auth()->user()->teams->pluck('id')->toArray());
        })->count();
    });
}

public static function getPermissionPrefixes(): array
{
    return [
        'view',
        'view_any',
        'create',
        'update',
        'delete',
    ];
}

public static function afterCreate($record): void
{
    // Set default role jika belum ada
    if (!$record->hasRole('pegawai')) {
        $record->assignRole('pegawai');
    }

    // Set default team jika belum ada
    if (!$record->teams->count()) {
        $record->teams()->attach(auth()->user()->teams->first()?->id);
    }
}

// Di UserResource.php, metode getEloquentQuery

public static function getEloquentQuery(): Builder
{
    // Perbaikan: Ubah query untuk menghindari konflik kolom id yang ambigu
    $query = parent::getEloquentQuery()->select('users.*');

    // Gunakan eager loading dengan constraints untuk menghindari ambigu select
    if (auth()->user()->hasRole('super_admin')) {
        return $query;
    }

    // Admin OPD hanya bisa lihat user di teamnya
    $teamIds = auth()->user()->teams->pluck('id');

    // Gunakan subquery dengan spesifikasi tabel.kolom yang jelas
    return $query
        ->whereExists(function ($q) use ($teamIds) {
            $q->select(\DB::raw(1))
                ->from('team_user')
                ->whereColumn('team_user.user_id', 'users.id')
                ->whereIn('team_user.team_id', $teamIds);
        })
        ->whereNotExists(function ($q) {
            $q->select(\DB::raw(1))
                ->from('model_has_roles')
                ->join('roles', 'roles.id', '=', 'model_has_roles.role_id')
                ->whereColumn('model_has_roles.model_id', 'users.id')
                ->where('roles.name', 'super_admin')
                ->where('model_has_roles.model_type', User::class);
        });
}

}

Sinnbeck's avatar

@doniaries Try changing this line

return $query->whereIn('id', auth()->user()->teams->pluck('id'));
//to
return $query->whereIn('teams.id', auth()->user()->teams->pluck('id'));
juanborras's avatar

Oh God!

I have the same problem "Integrity constraint violation: 1052 Column 'curso_academico_id' in where clause is ambiguous" but i don't know where can I modify the query due it is a RelationManager and I don't know where to specify which "curso_academico_id" should the query use.

Any ideas? Thank you very much

Snapey's avatar

@juanborras prefix the column name where you use it. If its in a relationship then edit it in the relationship definition.

But, really, start your own question

juanborras's avatar

It's a RelationManager, the only place i see the relation is defined is at the beggining of the class: protected static string $relationship = 'partes'; Where can I specify that for the column 'curso_academico_id' use the partes table?

juanborras's avatar

Fixed. Added the table name in the Scope class I'm using

class CursoAcademicoActualScope implements Scope
{
    public function apply(Builder $builder, Model $model): void
    {

        $builder->where($model->getTable().'.curso_academico_id', CursoAcademico::activo()?->id);
    }
}

Please or to participate in this conversation.