Search code examples
laravelpolicy

Laravel policies are resolving weird


I need a policy to create trees in a tournament.

So, In my treeController@store, I have:

if (Auth::user()->cannot('generateTree', new Tree(),$tournament)) {
        throw new AuthorizationException();
}

And my corresponding policy is :

TreePolicy.php:

public function generateTree(Tree $tree, Tournament $tournament )
{
    dd($tournament);
    return ($tournament->user_id == Auth::user()->id);
}

And I get a :

Type error: Argument 1 passed to App\Policies\TreePolicy::generateTree() must be an instance of App\Tree, instance of App\User given, called in /laravel/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 382

What am I missing???

EDIT : In response to @andonovn,

I tried it with :

public function store(User $user, Tree $tree, Tournament $tournament)
{
    dd($tournament);
}

And

    if (Auth::user()->cannot('generateTree', Tree::class,$tournament)) {
        throw new AuthorizationException();
    }

--> it gives me a 403

Or

$this->authorize('store',  $tournament,Tree::class);

--> it doesn't enter the dd();

The only way I found it to work is putting the Policy content in the controller which is not so nice:

if ($tournament->user_id != Auth::user()->id){
        throw new AuthorizationException();
    }

EDIT 2 : I solve it with that:

In controller :

if (Auth::user()->cannot('store', [Tree::class,$tournament])) {
        throw new AuthorizationException();
    }

In policy

public function store(User $user, Tournament $tournament)
{
    return ($tournament->user_id == $user->id);
}

Solution

  • I believe the first argument of generateTree() must be the authenticated user. Try changing it to public function generateTree(User $user, Tree $tree, Tournament $tournament )

    Edit: Also change the cannot method to Auth::user()->cannot('generateTree', [Tree::class, $tournament]) (combine the 2nd and 3rd parameters in array, seems like Laravel is always expecting 2 arguments where the 2nd one can be array)