Custom Routes in Laravel

885 views Asked by At

So I have routing scheme like below. When URIlooks like "audi-a4-modification-category" - it work's fine. But when I have uri like "alfa-romeo-giulietta-modification-category", becouse Laravel thinks alfa - brand, romeo - model ... and I'm getting wrong method from controller. How can I fix that, without changing delimiter in URI?

Route::get('{brand}-{model}-{modification}-{category}', 'Frontend\PagesController@category')->middleware('custom-routing')->name('frontend.category');
Route::get('{brand}-{model}-{modification}', 'Frontend\PagesController@modification')->middleware('custom-routing')->name('frontend.modification');
Route::get('{brand}-{model}', 'Frontend\PagesController@model')->middleware('custom-routing')->name('frontend.model');
Route::get('{brand}', 'Frontend\PagesController@brand')->middleware('custom-routing')->name('frontend.brand');
2

There are 2 answers

0
MaartenDev On

The laravel docs state the following:

Route parameters are always encased within {} braces and should consist of alphabetic characters, and may not contain a - character. Instead of using the - character, use an underscore (_).

More info: https://laravel.com/docs/5.8/routing#required-parameters

A workaround would be to replace the url parts before generating the url:

The route:

Route::get('{brand}-{model}-{modification}-{category}', 'Frontend\PagesController@category')->middleware('custom-routing')->name('frontend.category');

The link:

<a href="{{ route('frontend.category', [str_replace('-', '_', 'alfa-romeo'), 'giulietta', 'modification', 'category']) }}">test</a>

The controller:

class PagesController
{
    public function category(...$args)
    {
        // or use list(...)
        [$brand, $model, $modification, $category] = array_map(function($urlPart) {
            return str_replace('_', '-', $urlPart);
        }, $args);

        return 'test';
    }
}
0
Prafulla Kumar Sahu On

You can define a mutator in model, something like

protected $appends = ['slug'];

and

public function getSlugAttribute() {
    $slug = $this->brand . '-' . $model . '-' . $modification . '-' . $category;
    return $slug;
}

now, it is just a model property and you can use route-model binding concept

public function getRouteKeyName()
{
    return 'slug';
}

all in your eloquent model and in controller

public function show(YourModel $slug) {
    return $slug;//your model instance
}

Not tested, but it should work fine.