1
votes

I want to update a post. Creating and deleting a post works perfectly but whenever I try to update it with a PATCH form, it fails and gives a MethodNotAllowedHttpException.

My routes.php:

...
Route::resource('posts', 'PostsController');
... 

Which gives me the following list of possible routes (pasted in css to keep it readable):

| GET|HEAD  | posts                    | posts.index          | App\Http\Controllers\PostsController@index   
| POST      | posts                    | posts.store          | App\Http\Controllers\PostsController@store    
| GET|HEAD  | posts/create             | posts.create         | App\Http\Controllers\PostsController@create     
| GET|HEAD  | posts/{posts}            | posts.show           | App\Http\Controllers\PostsController@show        
| DELETE    | posts/{posts}            | posts.destroy        | App\Http\Controllers\PostsController@destroy        
| PUT|PATCH | posts/{posts}            | posts.update         | App\Http\Controllers\PostsController@update      
| GET|HEAD  | posts/{posts}/edit       | posts.edit           | App\Http\Controllers\PostsController@edit   

My edit.blade.php (url= localhost:8000/posts/1/edit):

 {!! Form::model($post, ['method' => 'PATCH', 'action' => ['PostsController@update', $post]]) !!}
        @include('posts/_form', array('submitText' => 'Update'))
   {!! Form::close() !!}

And my PostsController:

public function update(Request $request, Post $post) {
        $post->update($request->all());
         return Redirect::route('posts.index')->with('message_succes', 'Post updated');
}

Whatever I try, it fails with a

MethodNotAllowedHttpException RouteCollection->methodNotAllowed(array('GET', 'HEAD', 'POST')) in RouteCollection.php line 206

Looking at the html source of the form the PATCH and token is inserted properly. When changing the PATCH to post in the form, it will use the store function and creates a new post. What do I need to do to update the post?

4
You should pass only an id with form action. You used $post. As you you didn't share edit() method, we don't know what returns in $post variable. If $post is a collection, use ['PostController@update',$post->id]. If not work, please share the edit() method's code.smartrahat
@smartrahat Yes you're right. Already found out that I was indeed posted the complete object. It's working now.Trekdrop

4 Answers

2
votes

Turns out that I was posting the complete object and not only the ID. I had to change:

$post to $post->id in the form and the PostController update to:

  public function update(Request $request, $post_id) {
        $post = Post::findOrFail($post_id)
        $post->update($request->all());
         return Redirect::route('posts.index')->with('message_succes', 'Post updated');
}
0
votes

Try to change the PATCH method to put in the form like this :

{!! Form::model($post, ['method' => 'PUT', 'action' => ['PostsController@update', $post]]) !!}
    @include('posts/_form', array('submitText' => 'Update'))
{!! Form::close() !!}
0
votes

For those, who just forgot to specify action/route for edit form, i.e.:

{!! Form::model($post, ['method' => 'PATCH']) !!}
    ...
    Form controls
    ...
{!! Form::close() !!}

If you don't explicitly specify update form action on edit page, Form::model() would use current route, e.g. <site>/posts/<id>/edit. So, don't forget about real update action location, either via route:

{!! Form::model($post, ['method' => 'PATCH', 'route' => ['posts.update', $post]]) !!}
    ...
    Form controls
    ...
{!! Form::close() !!}

... which I personally prefer, 'couse it's more universal, or via action:

{!! Form::model($post, ['method' => 'PATCH', 'action' => ['PostsController@update', $post->id]]) !!}
    ...
    Form controls
    ...
{!! Form::close() !!}

... which is slightly over-verbose and specific.

-1
votes

Nice, you're correct ! but you commented reverse, $post->id to $post then the controller will use the entire object instead the single. Now worked here. Thanks!