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

mehdi79's avatar

I'm struggling with Laravel 11 policies

I'm using Laravel + Livewire, I have a model named Todo located in App\Models, a policy named TodoPolicy located in App\Policies and a Livewire component named todolist located in App\Livewire\Elements\Todolist folder. according to Laravel 11 documentation, Laravel automatically register this policy, but it's not hapennig, also I have tried registering policy manually but it did'nt solve problem and always return 403 error.

0 likes
18 replies
mehdi79's avatar

@tykus component

class Todolist extends Component
{
    public $description;

    public function done($id) {
        sleep(0.5);
        todo::where('id',$id)->first()->update([
            'is_done' => true,
        ]);
    }

    public function restore($id) {
        sleep(0.5);
        todo::where('id',$id)->first()->update([
            'is_done' => false,
        ]);
    }

    public function delete($id) {
        sleep(0.5);
        todo::where('id',$id)->first()->delete();
    }

    public function add(todo $todo) {
        $this->authorize('create',$todo);
        
        $this->validate([
            'description' => ['required','max:128'],
        ]);
        sleep(0.5);
        todo::create([
            'user_id' => session('user_id'),
            'description' => $this->description,
        ]);
        $this->reset();
    }

    public function render()
    {
        return view('livewire.elements.todolist.todolist',[
            'todos' => todo::orderBy('is_done','ASC')->orderBy('created_at','DESC')->get(),
        ]);
    }
}

policy

namespace App\Policies;

use App\Models\User;
use App\Models\Todo;
use Illuminate\Auth\Access\Response;

class TodoPolicy
{
    /**
     * Determine whether the user can view any models.
     */
    public function viewAny(User $user): bool
    {

    }

    /**
     * Determine whether the user can view the model.
     */
    public function view(User $user, todo $todo): bool
    {

    }

    /**
     * Determine whether the user can create models.
     */
    public function create(User $user): bool
    {
        return true;
    }

    /**
     * Determine whether the user can update the model.
     */
    public function update(User $user, todo $todo): bool
    {
        //
    }

    /**
     * Determine whether the user can delete the model.
     */
    public function delete(User $user, todo $todo): bool
    {
        //
    }

    /**
     * Determine whether the user can restore the model.
     */
    public function restore(User $user, todo $todo): bool
    {
        //
    }

    /**
     * Determine whether the user can permanently delete the model.
     */
    public function forceDelete(User $user, todo $todo): bool
    {
        //
    }
}
tykus's avatar

@mehdi79 the create Policy method does not take an instance of the Model; there is no Model instance.

public function add()
{
    $this->authorize('create', todo::class);

    // ...
tykus's avatar

@mehdi79 I wonder if the non-conventional Model name (todo rather than Todo) is your issue

mehdi79's avatar

@tykus I use Todo and TodoPolicy, also tested todo and todoPolicy , thats not problem

mehdi79's avatar

@tykus I don't use Laravel Authentication system and I built it myself, also in this case I'm returning true for all create requests in policy just to test it.

tykus's avatar
tykus
Best Answer
Level 104

@mehdi79 now we're getting to the source of the issue - the create Policy method is expecting an authenticated User? Make it optional if you're not authenticated:

public function create(?User $user): bool
{
    return true;
}
3 likes
mehdi79's avatar

also i had updated composer. I have same problem with gate

mehdi79's avatar

@tykus It's Todo but also tested todo, I'm testing and trying for 2 days

rickt96's avatar

I'm facing the same issue here, using Filament 3 on Laravel 11. My model is neasted in \Cms subfolder inside App\Models, so i've manually registered the policy inside AppServiceProvider but policy is ignored

use App\Models\Cms\Category;
use App\Policies\CategoryPolicy;
use Illuminate\Support\Facades\Gate;

class AppServiceProvider extends ServiceProvider
{
	...
	
	Gate::policy(Category::class, CategoryPolicy::class);
	...
}
MohamedKarbawy's avatar

@rickt96 You can do something like that

public function __construct(?Category $category, $id)
{
	Gate::authorize('updateCategory', $category->find($id));
}

in your policy

public function updateCategory(?User $current_user, ?Category $category)
{
	//your logic here
}

for create it's simple

public function __construct()
{
	Gate::authorize('createCategory');
}
public function createCategory(?User $current_user)
{
	//your logic here
}
creekmore108's avatar

Great course so far! I'm stuck on episode 23 (6 steps to Author...) I created the policy JobPolicy and when I have a User with ID 1, an Employer with ID 1 and a Job_Listing with ID of 1 and I use 'can' in the Route::...'edit' or in the blade @can, it fails. I brought up the $job in tinker and all the ID's lie up and it should pass the 'can' but it's not. Any suggestions on what I'm doing wrong? (I referenced the source code and still can't find it, thinking it's a config or cache issue?) Thanks again, awesome job on the course and the site overall.

Please or to participate in this conversation.