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

red_devil's avatar

Admin Gate not working

Hi all,

I am trying to create a custom gate that allows users of the "Administrator" team to access the Users index page. However, it functions exactly the opposite of what I want to achieve and I do not seem to understand where am I wrong here.

Help is appreciated. Thank you.

User Model

/**
     * Check if the user belongs to Administrator Team
     * @param string $team
     * @return bool
     */

    public function belongsToAdmin(string $team)
    {
        return null !== $this->teams()->where('name', $team)->first();
    }

AuthServiceProvider

/**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Gate::define('is-admin', function ($user){

            return $user->belongsToAdmin('Administrator');
        });
    }

index.blade.php

 @foreach($users as $user)
                    @can('is-admin', $user)
                        <tr>
                            <th scope="row">{{ $user->user_id }}</th>
                            <td>{{ $user->name }}</td>
                            <td>{{ $user->email }}</td>
                            <td>{{ $user->created_at }}</td>
                            <td>{{ $user->updated_at }}</td>
                            <td>
                                <a class="btn btn-sm btn-primary" href="{{ route('admin.users.edit', $user->user_id) }}"
                                   role="button">Bearbeiten</a>
                                <button type="button" class="btn btn-sm btn-danger"
                                        onclick="event.preventDefault();
                                            document.getElementById('delete-user-form-{{ $user->user_id }}').submit()">
                                    Löschen
                                </button>
                                <form id="delete-user-form-{{ $user->user_id }}"
                                      action="{{ route('admin.users.destroy', $user->user_id) }}" method="POST"
                                      style="display: none">
                                    @csrf
                                    @method("DELETE")
                                </form>
                            </td>
                        </tr>
                    @endcan
                @endforeach

UserController

   /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        if (Gate::allows('is-admin')) {
            return view('admin.users.index', ['users' => User::paginate(10)]);
        }

        dd('you need to be admin!');

    }

Output :

Image

0 likes
9 replies
martinbean's avatar

@red_devil I don’t really understand your method. Why are you passing a “name” if you’re checking the user belongs to an “admin” team? Just do that check instead:

class User extends Authenticatable
{
    public function teams()
    {
        return $this->belongsToMany(Team::class);
    }

    public function isAdmin()
    {
        return $this->teams()->where('name', '=', 'Administrator')->exists();
    }
}

That will check if the user belongs to a team with the name of “Administrator”, and return true if they do.

red_devil's avatar

@martinbean I already tried this approach. However, my relationship is strict and it is a one-to-many relationship.

Like this

public function teams()
    {
        return $this->belongsTo(Team::class);
    }

Is this causing the problem?

martinbean's avatar

@red_devil No different. Just check the name of the related team model in that case:

public function isAdmin()
{
    return $this->team && $this->team->name === 'Administrator';
}
red_devil's avatar

@martinbean Ok so I tried this and dumped out the result.

    public function isAdmin()
    {
//        return null !== $this->teams()->where('name', $team)->first();
//       return $this->teams()->where('name','=', 'Administrator')->exists();
        $test = $this->team && $this->team->name === 'Administrator';
        dd($test);
    }

But, the boolean always return false regardless of the user associated with an Administrator or another team.

Image

martinbean's avatar

@red_devil Then check your relations.

If your user model has a team relation, then the code should return the result. And if that team has a name of Administrator, then the method should return true.

red_devil's avatar

@martinbean I have checked my relationships twice.

User.php

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'team_id',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    protected $primaryKey = 'user_id';

    public function answers()
    {

        return $this->hasMany(Result::class);
    }

    public function setPasswordAttribute($password)
    {
        $this->attributes['password'] = bcrypt($password);
    }

    public function teams()
    {
        return $this->belongsTo(Team::class);
    }

Team.php

class Team extends Model
{
    protected $fillable = [
        'name'
    ];

    public function users(){
        return $this->hasMany(User::class);
    }

}

I tried "teams" instead of "team" but the same result. Do you see any problem here?

martinbean's avatar

@red_devil Yes. If it’s a belongs-to relationship then it should be named singularly. A user belongs to one team, not teams.

1 like
red_devil's avatar
red_devil
OP
Best Answer
Level 1

So after a couple of days of debugging, I realized that my teams() method should be team() inside the User model as the user has only one team and BelongsTo relation will only return one record.

Thanks to @martinbean for the right direction. Appreciated your help.

Please or to participate in this conversation.