The issue is likely related to the way Laravel's resource routes work and how route model binding interacts with soft-deleted models.
Common Causes
-
Resource Route Conflict
Even though you defined your custom route before theRoute::resource('users', UserController::class);, resource routes can still cause conflicts, especially if the{user}parameter is not matching as expected. -
Route Model Binding with Soft Deletes
If yourUsermodel uses soft deletes (use SoftDeletes;), then by default, Laravel's route model binding will not retrieve soft-deleted models. So, if you're trying to restore a soft-deleted user, the{user}parameter will not resolve, and the route will not be found.
Solution
1. Explicitly Bind Soft Deleted Models
You need to tell Laravel to include soft-deleted models when binding the {user} parameter. You can do this in your RouteServiceProvider:
use App\Models\User;
use Illuminate\Support\Facades\Route;
public function boot()
{
parent::boot();
Route::bind('user', function ($value) {
return User::withTrashed()->where('id', $value)->firstOrFail();
});
}
2. Double-check the Form Method and Route Name
Make sure your form is using the correct HTTP method (PUT) and the correct route name:
<form method="POST" action="{{ route('users.restore', $user->id) }}">
@csrf
@method('PUT')
<button type="submit">Restore</button>
</form>
3. Check for JavaScript or Frontend Issues
If the route is found when rendering the form but not when submitting, ensure that:
- There are no JavaScript errors hijacking the form submission.
- The form is not being submitted via AJAX to a different URL/method.
4. Verify Route List
Run php artisan route:list and check that your users/{user}/restore route is present and not shadowed by a resource route.
Summary
The most common cause in your scenario is soft-deleted users not being resolved by route model binding. Use withTrashed() in your route binding to fix this.
Let me know if you need more help!