Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5.4 - Updating a resource

I'm building a blog post to learn Laravel 5.4 and am struggling to find any examples of how to update a Post anywhere.

My form is as follows

<form method="POST" action="/posts/{{ $post->id }}/edit">
    {{ csrf_field() }}

    <div class="form-group">
        <label for="title">Title</label>
        <input name="title" type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value="{{ $post->title }}" required>
    </div>
    <div class="form-group">
        <label for="description">Description</label>
        <input name="description" type="text" class="form-control" id="exampleInputPassword1" value="{{ $post->title }}" required>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-primary">Update</button>
    </div>
</form>

My Routes are as follows

Route::get('/posts/{post}/edit', 'PostsController@edit');

Route::patch('/posts/{post}', 'PostsController@update');

And my controller methods are

public function edit( Post $post )
{
    return view('posts.edit', compact('post'));
}

public function update(Request $request, Post $post )
{
    Post::where('id', $post)->update($request->all());

    return redirect('home');

}

I get a MethodNotAllowedHTTPException error but am not sure which part / parts of this I am getting wrong.

I'm assuming it must be the point at which I'm using the PATCH function, or potentially just the way I'm mass-assigning the new values. Any help would be greatly appreciated.

like image 901
rushtoni88 Avatar asked Jul 03 '17 10:07

rushtoni88


2 Answers

you should use

{{ method_field('PATCH') }}

as your form field

and change action to

/posts/{{ $post->id }}

like this:

<form method="POST" action="/posts/{{ $post->id }}">

        {{ csrf_field() }}
{{ method_field('PATCH') }}
        <div class="form-group">
            <label for="title">Title</label>
            <input name="title" type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value="{{ $post->title }}" required>
        </div>
        <div class="form-group">
            <label for="description">Description</label>
            <input name="description" type="text" class="form-control" id="exampleInputPassword1" value="{{ $post->title }}" required>
        </div>

        <div class="form-group">

            <button type="submit" class="btn btn-primary">Update</button>

        </div>

    </form>
like image 153
Mohammad Fanni Avatar answered Nov 10 '22 05:11

Mohammad Fanni


There are a couple of things you have missed out.

Firstly, as @Maraboc pointed out in the comments you need to add method spoofing as standard HTML forms only allow for GET and POST methods:

<input type="hidden" name="_method" value="PATCH">

or

{{ method_field('PATCH') }}

https://laravel.com/docs/5.4/routing#form-method-spoofing

Then you will also need to omit the "edit" uri in your forms action:

<form method="POST" action="/posts/{{ $post->id }}">

or

<form method="POST" action="{{ url('posts/' . $post->id) }}">

https://laravel.com/docs/5.4/controllers#resource-controllers

(scroll down a little bit to the Actions Handled By Resource Controller section)

You also may find it helpful to watch https://laracasts.com/series/laravel-5-from-scratch/episodes/10

Hope this helps!

like image 4
Rwd Avatar answered Nov 10 '22 05:11

Rwd