nested resources in laravel not worked - laravel

I want to have nested resources like that:
Route::group(['prefix' => 'manage', 'middleware' => ['role:boss']], function ()
{
Route::resource('/articles', 'ArticleController');
Route::group(['prefix' => '/articles', 'as' => 'articles.'], function () {
Route::resource('/types', 'ArticleTypeController');
});
});
But nested route for "article/type" doesn't work, I check my ArticleTypeController outside the "article" route and work.
I really confused, Everybody can help me?
and here is my controller:
class ArticleTypeController extends Controller
{
public function index()
{
$types = ArticleType::all();
return view('manage.articles.types.index')->withtypes($types);
}
}

Route::group(['prefix' => 'manage', 'middleware' => ['role:boss']], function ()
{
Route::get('articles/types', 'ArticleTypeController#articleTypeMethod');
Route::resource('articles', 'ArticleController');
Route::resource('articles.types', 'ArticleTypeController');
});
for nested resources use articles.types. plural naming is good.
now that manage/articles and manage/articles/1/types will work.
If you want to put a custom route, put it above the resource route if the controller has been used as a resource. see the articles/types [GET] route which maps to ArticleTypeController's articleTypeMethod. now this way http://localhost.com/manage/articles/types should work
here is the 5.1 documentation and it has been removed from documentation of 5.5. but have a look at what Taylor said about it here
it's not recommended on REST to use index function for articles/types, a nested resources index method is used like articles/{id}/types.
for articles/types you need to create a new method.
but if you still want to do it like that. just make it like this
Route::group(['prefix' => 'manage', 'middleware' => ['role:boss']], function ()
{
Route::get('articles/types', 'ArticleTypeController#index');
Route::resource('articles', 'ArticleController');
Route::resource('articles.types', 'ArticleTypeController', ['except' => ['index']]);
});

Related

Laravel and routing

i have a larvel 8 project with other package and route and configured my route like this:
Route::group(['prefix' => config('site.route_prefix', 'site'), 'middleware' => config('site.route.middleware', 'web')], function () {
Route::get('/post/search/{q?}', [SearchController::class, 'search'])->name('site.search.query');
...
like this my search route not working, and the search method isnot handled.If i added some text to the route like this, then it work:
Route::group(['prefix' => config('site.route_prefix', 'site'), 'middleware' => config('site.route.middleware', 'web')], function () {
Route::get('/fdgfgfdgfdg/post/search/{q?}', [SearchController::class, 'search'])->name('site.search.query');
my question is where this behavior come from ?

Laravel Localization prefix - URl "/" not working without locale

I've did whats written in this post in order to add Localization prefixes to my URLs. However when I visit "/" there is an error: NotFoundHttpException in RouteCollection.php line 161:.
This is my Routesfile web.php:
Route::get('/', ['uses' => 'MainController#showMainPage', 'as' => 'showMainPage']);
Route::group(['prefix' => 'backend'], function () {
Route::get('/login', ['uses' => 'UserController#agentLogin', 'as' => 'agentLogin']);
});
Function:
class MainController extends Controller
{
public function showMainPage()
{
return redirect()->route('/fr');
}
}
localhost:8000/fr and localhost:8000/en are working fine.
How can I redirect / to the fallback locale (/fr)?
You can try make lang param optional:
'prefix' => '{lang?}'

Multi domain routing in Laravel 5.2

I have setup multi-domain routing in my laravel 5.2 app. What I want to achieve is if a user hits, membership.app, he should be served different homepage as compared to user who hits, erp.app domain.
Route::pattern('erp', 'erp.app|erp.domain.com');
Route::pattern('membership', 'membership.app|membership.domain.com');
Route::group(['middleware' => ['web', 'auth'], 'domain' => '{erp}'], function() {
Route::get('/', 'HomeController#getIndex');
Route::controller('members', 'MembersController');
Route::controller('users', 'UsersController');
Route::controller('settings', 'SettingsController');
});
Route::group(['middleware' => 'web', 'domain' => '{erp}'], function () {
Route::controller('auth', 'Auth\AuthController');
});
Route::group(['middleware' => 'web', 'domain' => '{membership}'], function () {
Route::controller('/', 'BecomeMemberController');
});
Route::group(['middleware' => 'web'], function () {
Route::controller('ajax', 'AjaxController');
});
I tried this setup, but it breaks the code with first param in each controller method being the url instead of intended value.
Suppose I have a method hello in members controller.
public function hello($param1, $param2)
{
....
}
If I access erp.app/members/hello/1/2 url and try to print out $param1 of controller method, it returns erp.app instead of intended 1 in this case.
Please help.
I don't know why aren't you seperating the routes to different controllers as you say the output will be quite different...
A quick example of to use that:
Route::group(['domain' => '{type}.myapp.com'], function () {
Route::get('members/hello/{id1}/{id2}', function ($type, $id1, $id2) {
// when you enter --> members.myapp.com/hello/12/45
var_dump($type); //memebers
var_dump($id1); //12
var_dump($id2); //45
});
});

Laravel 4 : Route returning wrong information

I am setting up an API with Laravel so that I can connect with an AngularJS front-end.
I have 2 routes that go to the same controller method -> BallController#getSpecs
My routes are set up as follows:
Route::group(['prefix' => '/api/v1', 'before' => 'auth.basic'], function() {
Route::group(['prefix' => '/ball'], function() {
Route::get('/', 'BallController#getIndex');
Route::get('{id}', 'BallController#getIndex');
Route::get('specs', 'BallController#getSpecs');
Route::get('{id}/specs', 'BallController#getSpecs');
});
});
Now I am having trouble with Route::get('specs', 'BallController#getSpecs'); route.
The getSpecs method is defined as follows:
public function getSpecs($id = null)
{
if(empty($id))
{
Ball::all()->each(function($ball) {
$json = [$ball->id => [
'name' => $ball->name,
'core' => $ball->core->toArray(),
'coverstock' => $ball->coverstock->toArray(),
'finish' => $ball->finish->toArray(),
'manufacturer' => $ball->manufacturer->toArray()
]];
});
return Response::json($json);
}
else
{
$ball = Ball::find($id);
if(empty($ball))
{
return Response::json('You\'ve got no ballss', 404);
}
else
{
return Response::json([$ball->id => [
'name' => $ball->name,
'core' => $ball->core->toArray(),
'coverstock' => $ball->coverstock->toArray(),
'finish' => $ball->finish->toArray(),
'manufacturer' => $ball->manufacturer->toArray()
]]);
}
}
}
When I call /api/v1/ball/1/specs specifying an id I get the correct information back, however when I call /api/v1/ball/specs my function returns my error message 'You've got no balls'
ID should be null in this cast putting me into the first part of my if statement but for some reason I am getting into my else and getting my error because obviously no ID was provided and the ball won't exist.
Any help/insight will be appreciated.
Edit: I think it may be sending it to the wrong method. I think that /api/v1/ball/specs is being sent to BallController#getIndex instead of BallController#getSpecs.
The problem is in this part of the routing:
Route::get('{id}', 'BallController#getIndex');
Route::get('specs', 'BallController#getSpecs');
When it sees "/api/v1/ball/specs", it will actually call getIndex() with the "id" parameter set to "specs", because that's the first matching route. One way to fix it would be to define the "specs" route first before you define the "{id}" route. But a better solution would be to limit the accepted values of the "{id}" parmeter like this...
Route::get('{id}', 'BallController#getIndex')->where('id', '[0-9]+');
One other suggestion, there shouldn't be a leading "/" in your prefix values (apparently the code may be working anyway, but they aren't really supposed to be there. So the complete updated route might look like this...
Route::group(['prefix' => 'api/v1', 'before' => 'auth.basic'], function() {
Route::group(['prefix' => 'ball'], function() {
Route::get('/', 'BallController#getIndex');
Route::get('specs', 'BallController#getSpecs');
Route::get('{id}', 'BallController#getIndex')->where('id', '[0-9]+');
Route::get('{id}/specs', 'BallController#getSpecs')->where('id', '[0-9]+');
});
});

Add a function to a route?

Here's my route:
Route::get('log-in', array(
'as' => 'log-in',
'uses' => 'AuthController#getLogIn'
));
What's the best way to add in a test to it:
Route::get('log-in', function()
{
if (Auth::check())//do something
});
I know i could add it as a filter but I only need it on this route.
You cannot do both, have a function and a controller action in your route, so I see three options:
1) Add it as s filter, which is the best one.
2) Instantiate your controller inside that closure (anonymous function) and call the action from it.
3) Do the Auth::check() inside your controller or any service class called by your controller.
The auth filte already exists, why not use it?
Route::get('log-in', array(
'before' => 'auth',
'as' => 'log-in',
'uses' => 'AuthController#getLogIn'
));
You could create a filter in the 'app/filter.php' file like this:
Route::filter('myFilterName', function() {
if (!Auth::check())
{
return Redirect::route('MyNamedRoutToLoginPage');
}
});
Then you could use it in 'app/routes.php' file like this:
Route::group(array('before' => 'myFilterName'), function() {
// do your action here if user is logged
});

Resources