Reputation: 122
I have this route:
Route::get('{country}/{federalstate?}/{city?}', ['as' => 'regions.show', 'uses' => 'RegionsController@show']);
Next I have a model Country with a few countries in it.
I want this route only to take effect, when given {country} exists in the model Country. I want to do this, because don't wan to use a prefix for that route.
The ugly way would be a regular expression. Ugly, because I would have to update it every time I add a new country to the model.
So what's the best way to accomplish what I want to do?
Maybe this could help -> https://laravel.com/docs/5.4/routing#route-model-binding - but I am a beginner, and I can't get it to work.
edit:
this might work:
Route::get('{country?}/{federalstate?}/{city?}', ['as' => 'regions.show', 'uses' => 'RegionsController@show'])->where([
'country' => 'germany|usa|canada'
]);
But, as I said, I would have to change the Regex every time I add a new country to the database.
Upvotes: 2
Views: 3797
Reputation: 11
In my opinion, you could pass Country to your controller as model. If there is no such model in your DB, Laravel will produce 404 error.
Upvotes: 0
Reputation: 122
Here's my solution for now:
in AppServiceProvider in the boot() method:
$available_countries = Country::select('slug')->get();
$available_countries = $available_countries->toArray();
$tmp = array();
foreach ($available_countries as $country)
{
$tmp[] = $country['slug'];
}
Config::set('app.available_countries', $tmp);
and in my routes file:
Route::get('{country?}/{federalstate?}/{city?}', ['as' => 'regions', 'uses' => 'RegionsController@index'])->where([
'country' => implode('|', config('app.available_countries'))
]);
Upvotes: 1
Reputation: 1686
As you suggested, Route-Model binding may be your best bet. You can see from the docs that if the model you've bound to your route does not exist, the route will return a 404.
Just be aware that the default functionality in Route-Model binding expects an ID from the URL. If you want to override that, you can do the following:
/**
* Get the route key for the model.
*
* @return string
*/
public function getRouteKeyName()
{
return 'name';
}
Upvotes: 0