Does the User model use the HasRoles trait; assuming you are using Spatie's Laravel Permission package
Call to a member function map() on null
User.php
protected static function booted()
{
static::created(function (User $user) {
if (filament()->getCurrentPanel()->getId() === 'customer') {
$user->assignRole('customer');
}
if (filament()->getCurrentPanel()->getId() === 'admin') {
$user->assignRole('admin', 'super_admin');
}
});
}
public function canAccessPanel(Panel $panel): bool
{
if ($panel->getId() === 'customer' && $this->hasRole('customer')) {
return true;
}
if ($panel->getId() === 'admin' && $this->hasRole('admin', 'super_admin')) {
return true;
}
return false;
}

@tykus yeah I already use it in my User.php model and i use laravel permission v6
@devhoussam123 did you create your own roles relationship; or Accessor on the Model?
@tykus no I didn't
do you have a customer role?
@Snapey yeah I create the rules (customer, admin, super_admin) using seeder
@devhoussam123 where is the map function called, in assignRole I guessed? So, why then is $this->roles evaluating as null?
If you have not implemented roles (as a relation, accessor or property) yourself, then it should be an empty Collection (not null).
@tykus I don't know
@devhoussam123 show us your User model
User.php
<?php
namespace App\Models;
use App\Enums\AccountStatus;
use App\Enums\UserRoles;
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasAvatar;
use Filament\Panel;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Storage;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable implements FilamentUser, HasAvatar, MustVerifyEmail
{
use HasApiTokens;
use HasFactory;
use HasRoles;
use Notifiable;
use SoftDeletes;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'avatar_url',
'name',
'email',
'password',
'status',
'roles',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'status' => AccountStatus::class,
'roles' => UserRoles::class,
];
/**
* The "booted" method of the model.
*/
protected static function booted(): void
{
static::created(function (User $user) {
if (filament()->getCurrentPanel()->getId() === 'customer') {
$user->assignRole('customer');
}
if (filament()->getCurrentPanel()->getId() === 'admin') {
$user->assignRole(['admin', 'super_admin']);
}
});
}
public function canAccessPanel(Panel $panel): bool
{
if ($panel->getId() === 'customer' && $this->hasRole('customer')) {
return true;
}
if ($panel->getId() === 'admin' && $this->hasRole(['admin', 'super_admin'])) {
return true;
}
return false;
}
public function getFilamentAvatarUrl(): ?string
{
return $this->avatar_url ? Storage::url($this->avatar_url) : null;
}
}
@devhoussam123 you have a roles property that is fillable (and cast as UserRoles) on the Model, so I assume you have a roles column on the table also?
This is exactly the problem I mentioned above; you are overriding a property that the package implements as a relationship. If you are using the package, then you should not need your own roles column.
can you post the full error with stacktrace, or share the error using the share button on the error?
@devhoussam123 So this is the offending line
$currentRoles = $this->roles->map(fn ($role) => $role->getKey())->toArray();
and I'm concerned that $this->roles is messed up by your roles cast
Notice: When I remove the $table->string('roles')->default(UserRoles::Default); from users table it works
@devhoussam123 You are trying to have two ways of defining roles? With the same name!
@Snapey I want to get the current user rule in users table
@devhoussam123 again, it is not necessary to use the package and your own role column
Why do you name the column roles anyway?
@tykus I want to get the current role in users table?
@devhoussam123 don’t use the package in that case. This is t rocket science!!!
The documentation is clear about this.
https://spatie.be/docs/laravel-permission/v6/prerequisites
Must not have a [role] or [roles] property, nor a [roles()] method
Your User model/object MUST NOT have a role or roles property (or field in the database by that name), nor a roles() method on it. Those will interfere with the properties and methods added by the HasRoles trait provided by this package, thus causing unexpected outcomes when this package's methods are used to inspect roles and permissions.
Must not have a [permission] or [permissions] property, nor a [permissions()] method
Your User model/object MUST NOT have a permission or permissions property (or field in the database by that name), nor a permissions() method on it. Those will interfere with the properties and methods added by the HasPermissions trait provided by this package (which is invoked via the HasRoles trait).
// -----
just rename your column like
$table->string('current_role')->default(UserRoles::Default);
@arthvrian or role if it is expected to be a singular value property 🤷♂️
after I update the migration table now I get '403 FORBIDDEN' when I try to get access to filament dashboard
User.php
public function canAccessPanel(Panel $panel): bool
{
if ($panel->getId() === 'customer' && $this->hasRole([UserRoles::Customer]) && $this->hasVerifiedEmail()) {
return true;
}
if ($panel->getId() === 'admin' && $this->hasRole([UserRoles::Admin, UserRoles::SuperAdmin]) && $this->hasVerifiedEmail()) {
return true;
}
return false;
}
@devhoussam123 what values does the backed Enum UserRoles have?
@tykus ### UserRoles.php
<?php
namespace App\Enums;
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
enum UserRoles: string implements HasColor, HasIcon, HasLabel
{
case Customer = 'customer';
case Admin = 'admin';
case SuperAdmin = 'super_admin';
public const Default = self::Customer->value;
public function getColor(): string | array | null
{
return match ($this) {
self::Customer => 'primary',
self::Admin => 'info',
self::SuperAdmin => 'success',
};
}
public function getIcon(): ?string
{
return match ($this) {
self::Customer => 'bi-person',
self::Admin => 'bi-person',
self::SuperAdmin => 'bi-person',
};
}
public function getLabel(): ?string
{
return match ($this) {
self::Customer => __('Customer'),
self::Admin => __('Admin'),
self::SuperAdmin => __('Super Admin'),
};
}
}
@devhoussam123 (i) are they the values as the Role names in the package; (ii) is the role being assigned still and (iii) did you check which of the three conditions fails?
use a different name in your model, eg current_role
Now i WANT to be able to update the current role id from users table
@devhoussam123 Now; what has you done to solve the original issue?
@devhoussam123 If you just rename the column, why would you not be able to update it like any column?
Please or to participate in this conversation.