'Laravel redirect()->action not working and show missing parameters

PHP Version:7.2
Laravel Version:6.2

I am doing a simple project by laravel by article.
When I meet with redirect()->action, I am a little confused about that. I want to pass a variable named id by redirect()->action but it does't work.

Error Message is Missing required parameters for [Route: blog/post.show] [URI: blog/post/{post}].

If I remove the variable name, only pass the variable value and it would work. I read the manual but still could not understand the reason. Could you help me explain the logic. Thank you. Below is the sample code.

Router.php

Route::group(['prefix' => 'blog',
              'as' => 'blog/',
              'namespace' => 'Blog'],
              function(){
                    Route::resource('/post',"PostController");
              });



PostController.php

Create new blog post ( wrong )
Couldn't understant why this does't work ? Variable name($id) is the same.

    public function store(Request $request)
    {
        $post = new BlogPost;
        $post->title = $title;
        $post->content = $content;
        $post->save();

        return redirect()->action(
            'Blog\PostController@show', ['id' => $post->id]
        );
    }

Create new blog post ( correct )

    public function store(Request $request)
    {
        $post = new BlogPost;
        $post->title = $title;
        $post->content = $content;
        $post->save();

        return redirect()->action(
            'Blog\PostController@show', [$post->id]
        );
        //Or 'Blog\PostController@show', $post->id
    }

Show the new blog post

    public function show($id)
    {
        $post = BlogPost::find($id);
        if(! $post) {
            abort(404);
        }
        $content = $post->content;

        return view("blog.post", [
            "title" => $post->title,
            "content" => $content,
        ]);
    }

Thank you



Solution 1:[1]

Here is code :

return redirect()->route('routename', ['id' => 1]);

Solution 2:[2]

You got the error message because you are using the Resource Route and it will automatic bind the Model with Route

For More Info please refer: https://laravel.com/docs/6.x/routing#route-model-binding

Solution 3:[3]

I encountered this error myself when trying to use a redirect()->action. Here's a simple example that will fail in just the same way.

class SimpleController extends Controller {
    public function index() {
        return redirect()->action([static::class, 'show'], ['id' => 7]);
    }

    public function show($id) {
        // ... code goes here ...
    }
}

And in the routes somewhere:

Route::resource('somethingsimpler', SimpleController);

The reason this fails is because default stub used by Route::resource for show is the same as the resource name. Have a read here: https://laravel.com/docs/9.x/controllers#actions-handled-by-resource-controller

Solution 1

We could change our original example to using 'somethingsimpler' instead of 'id'.

class SimpleController extends Controller {
    public function index() {
        return redirect()->action([static::class, 'show'], ['somethingsimpler' => 7]);
    }

    public function show($id) {
        // ... code goes here ...
    }
}

And in the routes somewhere:

Route::resource('somethingsimpler', SimpleController);

However, this seems to negate the whole purpose of using redirect()->action.

Solution 2

Reading further in the same document linked above, it seems you can set the resource name https://laravel.com/docs/9.x/controllers#restful-naming-resource-route-parameters.

class SimpleController extends Controller {
    public function index() {
        return redirect()->action([static::class, 'show'], ['id' => 7]);
    }

    public function show($id) {
        // ... code goes here ...
    }
}

And in the routes somewhere:

Route::resource('somethingsimpler', SimpleController)->parameters([
    'somethingsimpler' => 'id'
]);

Solution 3 - Recommended

Reading the rest of the document, it becomes obvious that you can probably get away with not even naming the parameter.

class SimpleController extends Controller {
    public function index() {
        return redirect()->action([static::class, 'show'], [7]);
    }

    public function show($id) {
        // ... code goes here ...
    }
}

And in the routes somewhere:

Route::resource('somethingsimpler', SimpleController);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 aviboy2006
Solution 2 Urja Satodiya
Solution 3 SEoF