Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Route Model Autobinding Laravel Package

sebastiaanluca/laravel-route-model-autobinding

Automatically bind Eloquent models to Laravel route parameters using naming conventions, so {post} resolves to your Post model without manual Route::model definitions. Cuts boilerplate and keeps route files clean and predictable.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the honest framing: this package is deprecated and archived (last release September 2019), and its core value proposition — “I write {user} in a route and get a User instance without a type-hint” — was absorbed into Laravel itself as implicit route model binding back in 5.3. On anything from 5.3 through 11.x you get the same behaviour for free:

Route::get('/users/{user}', fn (User $user) => $user);

So step one is deciding whether you actually need the package. You do if you're maintaining a Laravel 5.x app that already depends on it, or you have a large set of legacy controllers/closures that receive raw route values and manually call Model::findOrFail(). If neither applies, stop here and use the framework.

If you are adopting it anyway:

  1. composer require sebastiaanluca/laravel-route-model-autobinding. On 5.4 and below, register SebastiaanLuca\RouteModelAutobinding\RouteModelAutobindingServiceProvider::class in config/app.php; 5.5+ auto-discovers it.
  2. Publish and read the config (php artisan vendor:publish --provider="SebastiaanLuca\RouteModelAutobinding\RouteModelAutobindingServiceProvider"). The single setting that matters is which namespace/directory the package scans or assumes for models — everything else is derived from that.
  3. Smoke-test it: hit /users/1 on a controller method declared as show($user) (no type-hint) and dd($user). If you get a User model, it's wired up; if you get the string "1", the binding didn't register.

Where to look first: the service provider (it's small — read it in vendor/sebastiaanluca/laravel-route-model-autobinding/src), then the config. The README is minimal and won't tell you more than the source will.

The first realistic use case is a legacy CRUD controller where every method opens with $user = User::findOrFail($id);. Those lines disappear, and the rest of the method keeps working because the variable is still a model.

Implementation Patterns

Convention-driven parameters. The package derives the model from the route parameter name: {user} → App\User, {blog_post} / {blogPost} → App\BlogPost. Naming discipline is therefore the whole integration. If your segment names don't singularise cleanly into a class name, you're fighting the package and should register an explicit binding instead.

Resource and nested routes. Route::resource('users', UserController::class) produces {user} and binds automatically. Nested resources (/users/{user}/posts/{post}) bind both segments — but see the scoping gotcha below before you rely on it.

Closures and non-type-hinted controllers. This is where it genuinely saves keystrokes. A closure function ($user) { ... } never had a place to put a type-hint without a use statement, so autobinding keeps route files terse.

Mixed with explicit bindings. Keep Route::model('author', User::class) (or Route::bind) for irregular segments — {author} will never resolve to App\User on its own. Treat the package as the default and explicit bindings as the escape hatch; don't register both for the same parameter and hope for a defined winner.

Migration shape. The cleanest way to adopt it in an existing app is route-by-route: pick one resource, delete the manual findOrFail, run the feature tests, move on. Doing it globally means a failure in the naming heuristic surfaces as a confusing TypeError deep in a controller rather than at the route you just changed.

Testing. Because resolution happens before your controller code, a missing or mis-named model shows up as a 404 (or a null) rather than an assertion failure. Keep at least one feature test per resource that asserts a 200 on a known-existing ID — that's your canary for the namespace heuristic breaking.

Gotchas and Tips

The Laravel 8 model namespace move will break this. The package predates Laravel 8's shift from App\ to App\Models\. If your models live in App\Models\User, the name-derivation heuristic looks in the wrong place and you get silent non-binding. Check the config for a base-namespace option; if it doesn't exist, this is fork territory.

Missing models: 404 vs null. Native implicit binding aborts with a 404. Verify what this package does when the record doesn't exist — a null injected into a method that then calls $user->id produces a fatal error instead of a clean 404, and that difference is user-visible and test-visible.

No scoped bindings. Laravel's ->scopeBindings() ensures a nested {post} belongs to {user}. A 2019 package has no notion of this: /users/1/posts/99 will happily resolve post 99 even if it belongs to user 2. If you have nested resources and any authorisation model beyond a policy check on the child, add an explicit Route::bind or a policy that verifies parentage. This is the one gotcha with security consequences.

Composer resolution on modern stacks. PHP 8 and Laravel 8+ constraints almost certainly won't satisfy the package's composer.json. Expect to fork it, or vendor the handful of classes into app/Support and drop the dependency.

Custom route keys aren't supported. {user:slug} is Laravel 7+ syntax. On this package, customise resolution via getRouteKeyName() on the model instead.

Route caching. Bindings registered from a service provider's boot survive php artisan route:cache, but any config-driven scan runs at boot using current config. If you change the model namespace or directory, clear the route cache before assuming the package is broken — and remember cached routes are a separate artifact from config cache.

Debugging. php artisan route:list won't show you bindings. Inspect the router directly (app('router')->getRoutes() and the binding callbacks) or just dd() inside the service provider's boot method to confirm which parameters it registered. Also confirm SubstituteBindings is in your web middleware group if resolution happens at dispatch time.

Extension point. The pragmatic move for a maintained app is not to extend this package but to replace it: native implicit binding plus getRouteKeyName() covers 95% of what it does, and Route::bind() covers the rest with no deprecation risk. If you must keep it, isolate it behind your own small service provider so a future swap is one file.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource