Norgul
Norgul

Reputation: 4783

Laravel routing strange behavior

I have a single domain/subdomain project. In order to see the event by slug, I made this route:

Route::prefix('events')->namespace('Content\Controller')->group(function () {
    Route::get('/', 'EventController@getIndex')->name('event.index');
    Route::get('{slug}', 'EventController@getView')->name('event.show');
    Route::get('{slug}/edit', 'EventController@getEdit')->name('event.edit');
    Route::post('load-more-ajax/{region?}', 'EventController@postLoadMoreAjax');
    Route::any('sorted-ajax/{region?}', 'EventController@anySortedAjax');
    Route::get('category/{category_slug}/{subcategory_slug?}', 'EventController@getCategory');
});

After my page didn't load correctly, I did a dump in the controller:

public function getView($slug)
{
    return $slug;
}

To get to the route I am using this URL: https://example.com/events/slug-example.

The problem is that the route is being hit as I see the response when I change it, but I am not getting the slug, instead I am getting Region object back.

If I do this:

public function getView($region, $slug)
{
    return $slug;
}

Then I get the slug back. But I have no idea how is this possible, and how could I do it (I came as another dev on the existing project).

I tried commenting out all the middleware and it is still the same. How can I even make something fill the method if I didn't explicitly say it?

EDIT

I noticed there is binding going on in routes file:

Route::bind('region', function ($value) {
    ...
});

Now if I dd($value) I get the variable back. How is this value filled? From where could it be forwarded?

Upvotes: 0

Views: 390

Answers (2)

Marcin Nabiałek
Marcin Nabiałek

Reputation: 111829

Looking quickly it should work, but maybe you was verifying other url.

Make sure you put:

Route::get('{slug}', 'EventController@getView')->name('event.show');
Route::get('{slug}/edit', 'EventController@getEdit')->name('event.edit');

routes at the end of routes you showed.

EDIT

If you think that's not the case and you don't have your routes cached you should run:

php artisan route:list

to verify your routes.

EDIT2

After explaining by OPs in comment, domain used for accessing site is:

{region}.example.com

So having $region in controller as 1st parameter is correct behaviour because of route model binding and other route parameters will be 2nd, 3rd and so on.

Upvotes: 1

Mathieu Ferre
Mathieu Ferre

Reputation: 4412

Instead of

Route::prefix('events')->namespace('Content\Controller')->group(function () {
    Route::get('/', 'EventController@getIndex')->name('event.index');
    Route::get('{slug}', 'EventController@getView')->name('event.show');
    Route::get('{slug}/edit', 'EventController@getEdit')->name('event.edit');
    Route::post('load-more-ajax/{region?}', 'EventController@postLoadMoreAjax');
    Route::any('sorted-ajax/{region?}', 'EventController@anySortedAjax');
    Route::get('category/{category_slug}/{subcategory_slug?}', 'EventController@getCategory');
});

try

Route::prefix('events')->namespace('Content\Controller')->group(function () {
    Route::get('/', 'EventController@getIndex')->name('event.index');
    Route::post('load-more-ajax/{region?}', 'EventController@postLoadMoreAjax');
    Route::any('sorted-ajax/{region?}', 'EventController@anySortedAjax');
    Route::get('category/{category_slug}/{subcategory_slug?}', 'EventController@getCategory');
    Route::get('{slug}', 'EventController@getView')->name('event.show');
    Route::get('{slug}/edit', 'EventController@getEdit')->name('event.edit');
});

Upvotes: 0

Related Questions