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

Bogey's avatar
Level 1

Spatie permissions not working

I'm using spatie permissions for roles and permissions management. I have 2 roles, admin and author.

admin doesn't have any permissions as I have set it through the provider to just return 'true' if the user has the role of admin but the role author has 3 permissions, to 'create', to 'update' and to 'delete' blog posts if the posts belong to the author.

For the admin everything works as expected, but for the author nothing works. author can't create new posts, they can't update their posts and they can't delete their posts...

In my create() method of my controller I have the following code at the very top of the method

// Checking if the user can create a blog post first... we don't want unauthorized users or guests to be able to make blog posts.
if(Auth::user() == null || Auth::user()->cannot('create', Auth::user()))
{
    return redirect(route('home'));
}

Visiting that route directly (as the link is hidden) I get redirected to my 'home' route. The code doesn't recognize that the user has the author role that has the permission to create a blog post.

In my view, I'm using the following code

@canany(['update', 'delete'], [$post])
<div class="bg-light p-3 text-start">
    <p class="small text-muted fw-semibold m-0 p-0">Manage Post</p>
    <ul class="list-group list-group-flush text-start border-top post-manager">
@can('update', $post)
        <li class="list-group-item small text-muted p-0 ms-4">
            <a href="{{ route('blog.edit', $post->post_slug) }}" class="stretched-link">Edit</a>
        </li>
@endcan
@can('delete', $post)
        <li class="list-group-item small text-muted p-0 ms-4">
            <a class="stretched-link" data-bs-toggle="modal" data-bs-target="#deletePost" role="button">Delete</a>
        </li>
@endcan
    </ul>
</div>
@endcanany

And that doesn't show anything for anyone that has the author role, but everything shows and works for the admin users...

I've checked the database, and everything is in there...

0 likes
4 replies
jbloomstrom's avatar

Maybe try this?

if(Auth::guest() || Auth::user()->cannot('create', Post::class))
{
    return redirect(route('home'));
}
Bogey's avatar
Level 1

Running php artisan migrate:refresh and then re-setting the database fixed some of the issues.

I renamed the permission names from create to createPost and that part works. And deletePost works but updatePost does not work.

For createPost, updatePost and deletePost I'm running the following checks.

// In the create and store methods...
if(Auth::user() == null || Auth::user()->cannot('createPost', Auth::user()))
{
    return redirect(route('home'));
}

// In the edit and update methods...
if(Auth::user() == null || Auth::user()->cannot('updatePost', Auth::user()))
{
    return redirect(route('home'));
}

// In the delete method...
if(Auth::user() == null || Auth::user()->cannot('updatePost', Auth::user()))
{
    return redirect(route('home'));
}

All of those work except for updatePost... I refuse to believe that the only way to fix it is to refresh the migrations and setting up the database again... why would that effect the permissions?

[EDIT] Removing the , Auth::user() from the cannot() method doesn't effect anything. It still allows to delete and create but not to update.

Once again, this only effects users that don't have the admin role... admin can do everything like I have it set up.

Bogey's avatar
Level 1

Nevermind... I had the permission named editPost but was using updatePost in the code.

Everything works... wonder why it only got fixed with a migrate:refresh... it was all already in the database, just under a different name

Please or to participate in this conversation.