Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

andyjameswhite's avatar

Web Route gives 404 with Implicit Binding

This must be the easiest solve ever, but somehow I cannot see what I've done wrong.

I can create a type hinted implicit binding in the web.php route file and dump the contents of a chosen booking, based on the ID contained in {$booking}

However when I do the same thing to hit the BookingController it gives me a 404.

For further reference the route /booking/create hits the BookingController and displays the create form just fine.

Web Route

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BookingController;
use Illuminate\Http\Request;
use App\Models\Booking;

//THIS WORKS FINE AND DUMPS THE BOOKING
Route::get('/booking/{booking}/', function (Booking $booking) {
    dd($booking);
})->name('booking.edit');

//THIS GIVES A 404
Route::get('/booking/{$booking}/', [BookingController::class, 'edit'])->name('booking.edit');

//THIS WORKS FINE
Route::get('/booking/create', [BookingController::class, 'create'])->name('booking.create');

BookingController

use Illuminate\Http\Request;
use App\Models\Booking;
use App\Models\Location;

class BookingController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }
     
    public function edit(Booking $booking)
    {
        dd('show edit blade here');
    }
    
    public function create()
    {
        $locations = Location::get();
        return view('admin.booking.create', compact('locations'));
    }

}

I've simplified a bit to boil down the question, I just can't believe this is not working.

All cache cleared etc

Help!

0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

The issue you're encountering is due to the incorrect usage of curly braces in your route definition. When defining routes in Laravel, you should not use curly braces within the route URL string itself. Instead, you should use the parameter name directly without the curly braces.

Here's the corrected version of your route definition:

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BookingController;
use App\Models\Booking;

// THIS WORKS FINE AND DUMPS THE BOOKING
Route::get('/booking/{booking}/', function (Booking $booking) {
    dd($booking);
})->name('booking.edit');

// THIS SHOULD WORK NOW
Route::get('/booking/{booking}/', [BookingController::class, 'edit'])->name('booking.edit');

// THIS WORKS FINE
Route::get('/booking/create', [BookingController::class, 'create'])->name('booking.create');

Notice that in the corrected route definition for the BookingController's edit method, the parameter is defined as {booking} without the dollar sign and curly braces.

Additionally, ensure that your Booking model is correctly set up for route model binding. Laravel automatically resolves the model instance based on the route parameter if the parameter name matches the model's route key (usually the primary key, id).

Your BookingController should work as expected with the corrected route definition:

use Illuminate\Http\Request;
use App\Models\Booking;
use App\Models\Location;

class BookingController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }
     
    public function edit(Booking $booking)
    {
        dd('show edit blade here');
    }
    
    public function create()
    {
        $locations = Location::get();
        return view('admin.booking.create', compact('locations'));
    }
}

With these changes, the route should correctly resolve the Booking model instance and pass it to the edit method of your BookingController.

Please or to participate in this conversation.