I'm trying to use the @hasrole() directive in my blade template, but I'm getting the following error:
FatalErrorException in HasRoles.php line 131:
Call to a member function contains() on null
in HasRoles.php line 131
If I dump $this->roles in HasRoles::hasRole() it return null, though the User is what I would expect and that object does have roles assigned to them (verified in the db, as well as via Auth::user()->roles()->get()).
Am I using it wrong, or missing some integration?
Blade template code:
@hasrole(['Admin'])
...
@endhasrole
User model:
<?php
namespace App\Models;
use Backpack\CRUD\CrudTrait;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Backpack\Base\app\Notifications\ResetPasswordNotification as ResetPasswordNotification;
class User extends Authenticatable
{
use Notifiable;
use CrudTrait;
use HasRoles;
...
Current setup:
Not sure if it's relevant but I'm using Backpack CRUD:
What's the output of auth()->user() and auth()->user()->hasRole($roleNameYouAreChecking) if you put those lines right before the failing @hasrole() directive? Do you see the roles on the user that is being returned there?
@freekmurze here is a gist with the output:
https://gist.github.com/benrasmusen/a96ecf5ea9582bb63da6207b45560bfd
The call to Auth::user()->hasRole('Admin') throws the same error as the directive. But you'll see that the dump of Auth::user() does contain the proper roles.
I cannot reproduce this error. If your model has hasRoles trait applied to it, it'll gain a roles relation that returns a collection when empty. Not sure why this fails on your end.
This is the line that I believe is failing at your end https://github.com/spatie/laravel-permission/blob/master/src/Traits/HasRoles.php#L131
Could you add a dd($this, $this->roles) statement right before that line to see what roles is set to there?
Yeah, it's really strange. The relations seem to be attached properly, but $this->roles isn't working as it should... it's frustrating. :/
I put the debug inside this conditional, above the return:
if (is_string($roles)) {
return $this->roles->contains('name', $roles);
}
Here is $this: https://gist.github.com/benrasmusen/24af1b0503a289269554ffb996d06ca8
$this->roles returns null
Do you use any magic methods in your model? Could you try setting this package up in a vanilla installation of Laravel?
Here is my entire User.php model:
<?php
namespace App\Models;
use Backpack\CRUD\CrudTrait;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Backpack\Base\app\Notifications\ResetPasswordNotification as ResetPasswordNotification;
class User extends Authenticatable
{
use Notifiable;
use CrudTrait;
use HasRoles;
protected $with = ['roles', 'permissions'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'first_name', 'last_name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Send the password reset notification.
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
public function getFullNameAttribute()
{
return ucfirst($this->first_name) . ' ' . ucfirst($this->last_name);
}
public function notes()
{
return $this->belongsToMany('App\Model\StudentNotes');
}
}
NOTE: I recently added the protected $with = ['roles', 'permissions']; param to retrieve the associations for user management in my CRUD controller. But I was experiencing the issue before I added that line.
Does anything look amiss to you?
If you don't see anything obviously wrong then I'll try to set something more vanilla up for testing. Since you're not able to recreate it, it seems like it's probably something wrong with my code.
It all looks good time me. I'm thinking that a call to roles should always return a collection. Not sure why in your case it returns null. @AlexVanderbist is going to investigate this further soon.
Hi @benrasmusen
I've installed all the Backpack packages you've mentioned and wasn't able to reproduce this issue... Did you add any other customizations that might've led to this? Any non-default settings for Laravel's database or caching?
I take it the roles and permissions aren't visible on the user page either? Does it throw an error or just display a blank table cell?
(shot in the dark; we've had some issues with caching before, you can always try flushing the permission cache with php artisan cache:forget spatie.permission.cache)
Hey @AlexVanderbist thanks for jumping in! :)
I haven't done much to modify anything related to the User model or Authentication. The only thing I can think of is that I move it from app/User.php -> app/Models/User.php not sure if that would affect anything...?
Not sure if this helps, but I did discover that if I use this: $this->roles()->get() instead of $this->roles it does return the correct roles for that user.
As to your question about the user edit page, it does actually retrieve the correct "roles" and "permissions" without any extra code. So, that's even more strange!
Can I dump any additional variable, or provide any more code to help diagnose the issue?
Hm, the relationships seem to have loaded alright but somehow a roles attribute is being set to null on the User model. What does your user table look like?
Wow, I feel like a complete idiot. 🤦♂️
There is a roles column in the users table. I created the schema for this awhile ago and haven't thought to check back on it since implementing laravel-permission.
If I remove that column everything is working as expected.
I am so sorry for wasting your time! I really appreciate all your help @AlexVanderbist and @freekmurze!
i have the same problem but can not remove this column now because re factor @AlexVanderbist and @freekmurze!
Most helpful comment
Wow, I feel like a complete idiot. 🤦♂️
There is a
rolescolumn in theuserstable. I created the schema for this awhile ago and haven't thought to check back on it since implementinglaravel-permission.If I remove that column everything is working as expected.
I am so sorry for wasting your time! I really appreciate all your help @AlexVanderbist and @freekmurze!