Adsy2010
Adsy2010

Reputation: 545

Method not allowed - redirect using incorrect method

I have been working on a simple Laravel Inertia Vue3 application. It has one resource route.

Route::resource('contact', \App\Http\Controllers\ContactController::class);

This provides the named routes contact.index .store .create .show .update .destroy and .edit

Nice and simple so far.

I have a useForm form variable in my Vue component with some assigned variables

let form = useForm({ ... });

I have a submit method in the same component

let submit = () => {
    if(props.edit) {
        form.patch(`/contact/${props.contact.id}`);
    } else {
        form.post(`/contact`);
    }
}

Again nothing complex. The post method fires off correctly and redirects

    Contact::query()->create($request->all());

    return redirect()->to(route('contact.index'));

For full disclosure of the update method, please see below:

public function update(Request $request, Contact $contact): \Illuminate\Http\RedirectResponse
{
    $contact->fill($request->all())->save();

    return redirect()->to(route('contact.show', ['contact' => $contact]));
}

This works in the same way as store. Simple and then redirects... but it doesn't.

What happens is that it runs the patch and then calls redirect The redirect carries the patch method through ending up with a 405 if I use the index route (declared as get). If I use back() I get the same thing. If I use the show route, it redirects in a loop because the patch route uses the same URL /contact/{contact}

I have built Laravel applications for the last 5 years and have not had an issue like this before when using a named route. Have I missed something basic? If not its possibly a configuration issue although I am not sure what.

I am running Laravel 9.19 with webpack manually installed as its been changed to Vite on the current release. I have no Vue errors or warnings and no Laravel logs.

Upvotes: 0

Views: 235

Answers (3)

Adsy2010
Adsy2010

Reputation: 545

This time I really am answering my own question.

I was a total idiot and missed a step when setting up inertia js. I was attempting to retrieve errors with the useform method and what happened was I received nothing.

So I though I would double check the docs.

Turns out I missed adding this middleware to the web middleware group in the kernel!

\App\Http\Middleware\HandleInertiaRequests::class,

I can now use the .patch method I had before and no need for any additional code

Upvotes: 0

Adsy2010
Adsy2010

Reputation: 545

So good ol' Laravel got me again.

Alexander Dyriavin got me on the right course with his answer about put and patch, however, it wasn't really the solution.

The solution:

    form.transform((data) => ({
        ...data,
        _method: 'PUT' //spoof added to request
    })).post(`/contact/${props.contact.id}`); //sent as a post instead

The Laravel docs allow you to spoof methods https://laravel.com/docs/5.0/routing#method-spoofing by posting them with a _method field.

Simply put, a patch or put request would have always failed with a redirect from Laravel. In the past I would have used them with Axios and handled a JSON response directly.

Upvotes: 0

Alexander Dyriavin
Alexander Dyriavin

Reputation: 209

there is a difference between PUT and PATCH requests on laravel-level. Please run php artisan route:list - and see which one is used in your case, There is a big chance that you using PUT, not patch :)

Upvotes: 1

Related Questions