Argument 2 passed to App\Providers\AuthServiceProvider::App\Providers\{closure}() must be an instance of App\Post

November 22, 2017

I am trying to implement policies in Laravel with the following code

I have a controller to update the Post

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;

class PostController extends Controller
{
    public function index(){
    
     return  view('post.index',['posts' => Post::all()]);

    }

    public function update($id){
    
     return  view('post.update',['post' => Post::findOrFail($id)]);

    }


}

And I have the Gate defined in AuthServiceProvider.php

   public function boot()
    {
        $this->registerPolicies();

         Gate::define('update-post', function ($user,Post $post) {
            return $user->id == $post->user_id;
         });
         


    } 

My Route for update the post like this

Route::get('post/update/{post}', 'PostController@update')
       	->name('update-post')
   		->middleware('can:update-post,post');

But when I open the following page http://localhost/dev/cc/laravel/user/public/post/update/1 I am getting the following error

Argument 2 passed to App\Providers\AuthServiceProvider::App\Providers\{closure}() must be an instance of App\Post, string given, called in /Applications/XAMPP/xamppfiles/htdocs/dev/cc/laravel/user/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 298 and defined

in AuthServiceProvider.php (line 30)

at HandleExceptions->handleError(4096, 'Argument 2 passed to App\\Providers\\AuthServiceProvider::App\\Providers\\{closure}() must be an instance of App\\Post, string given, called in /Applications/XAMPP/xamppfiles/htdocs/dev/cc/laravel/user/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 298 and defined', '/Applications/XAMPP/xamppfiles/htdocs/dev/cc/laravel/user/app/Providers/AuthServiceProvider.php', 30, array('user' => object(User)))in AuthServiceProvider.php (line 30)

Solution
This is a problem related to the implicit model binding in Laravel. To fix this issue you can do some change to the action in the PostController

 Post::all()]);

    }

    public function update(Post $post){
    
     return  view('post.update',['post' => $post]);

    }


}