Customize Route Model Binding in Laravel Using resolveRouteBinding()
The Default Behavior
In Laravel, route model binding automatically retrieves a model using its primary key.
Example:
Route::get('/products/{product}', function (Product $product) {
return $product;
});
Laravel runs something like:
Product::findOrFail($id);
But sometimes ID is not what you want.
Real Project Problem
Imagine you want to access products using slug instead of ID:
/products/macbook-pro
Instead of:
/products/25
The Solution: resolveRouteBinding()
You can customize how Laravel resolves the model.
Inside your model:
public function resolveRouteBinding($value, $field = null)
{
return $this->where('slug', $value)->firstOrFail();
}
Now Laravel automatically retrieves products using the slug column.
Route Example
Route::get('/products/{product}', function (Product $product) {
return $product->name;
});
URL:
/products/macbook-pro
Laravel automatically fetches the correct product.
Why This Is Useful
Using custom route binding helps you:
- Create SEO-friendly URLs
- Control how models are retrieved
- Add extra conditions (e.g., only published records)
Example with condition:
return $this->where('slug', $value)
->where('is_active', true)
->firstOrFail();
Now inactive products cannot be accessed.
When to Use It
Use custom route binding when:
- Using slugs instead of IDs
- Filtering models automatically
- Implementing public-friendly URLs
- Enforcing conditions globally