Laravel 7 automatic scoping in resource route - laravel

is there a way to use the new automatic scoping in resource routes? Everything I tried didn't work:
Route::apiResource('instances/{instance:id}/projects', 'ProjectController', [
'except' => ['destroy']
]);
The following manual solution is working but would be a mess in the routes file.
Route::get('instances/{instance:id}/project/{project:id}',function(Instance $instance, Project $project){
return response()->json($project);
});
Thanks

I had a similar problem and as far as I can tell, the custom route key needs to be specified on the nested resource to trigger automatic scoping. The easiest way to do it without specifying each route separately is probably using parameters():
Route::apiResource('instances.projects', 'ProjectController')->parameters([
'projects' => 'project:id'
]);

it is probably help you
Route::group(['prefix' => 'instances/{instance:id}'], function () {
Route::apiResource('project', 'ProjectController', [
'except' => ['destroy']
]);
});

it could be an issue your models are in some other directory. you have to resolve the models first to be injected.
public function boot()
{
parent::boot();
Route::model('instance', App\Instance::class);
Route::model('project', App\Project::class);
}
You have to explicitly bind the models to keys.
Route::get('instances/{instance:id}/project/{project:id}',function(Instance $instance, Project $project){
return response()->json($project);
});

Related

Laravel-5.8: route show don't return any values

In previous versions of Laravel I was using something like this in controller in show function
Route::resource( 'our-project', 'ProjectController' );
public function show( Project $project ) {
return view( 'portalComponents.projects.projectDetails', compact( 'project' ) );
}
I was trying the same in laravel 5.8 but the $project attributes comes empty.
Route model binding won't work for our-project/1 because laravel can't infer the model. It tries to bind the our-project placeholder to a variable that has the name name in the show method. That argument doesn't exist. Because if this the $project variable stays empty.
the following resource would work:
Route::resource( 'projects', 'ProjectController' );
because this uses the project placeholder in routes. Check the output from php artisan route:list
It is also possible to have the same resource with different prefixes:
Route::resource('projects', 'ProjectController');
Route::group(['prefix' => 'admin'], function () {
Route::resource('projects', 'ProjectController');
});
the first one is /projects/1 and the second one is /admin/projects/
For the sake of completness and as alternative to #MaartenDev right answer, if you want to define the name of the parameter used with a resource route you can use the parameters() function, i.e.:
Route::resource( 'our-project', 'ProjectController' )
->parameters(['our-project' => 'project']);

How to use multiple method in single route in laravel

I want to use more than one method in a single route using laravel. I'm try this way but when i dd() it's show the plan string.
Route::get('/user',[
'uses' => 'AppController#user',
'as' => 'useraccess',
'roles'=> 'HomeController#useroles',
]);
When i dd() 'roles' option it's show the plan string like this.
"roles" => "HomeController#useroles"
my middleware check the role this way.
$actions=$request->route()->getAction();
$roles=isset($actions['roles'])? $actions['roles'] : null;
The simplest way to accept multiple HTTP methods in a single route is to use the match method, like so:
Route::match(['get', 'post'], '/user', [
'uses' => 'AppController#user',
'as' => 'useraccess',
'roles'=> 'HomeController#useroles',
]);
As for your middleware, to check the HTTP request type, a tidier way would be:
$method = request()->method();
And if you need to check for a specific method:
if (request()->isMethod('post')) {
// do stuff for post methods
}
Here's how you can do multiple methods on a single route:
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
/* Would be easier to use
* Route::put('/route/{route}', 'RouteController#update');
* Since Laravel gives you the Model of the primary key you've passed
* in to the route.
*/
Route::delete('/route', 'RouteController#destroy');
If you've written your own middleware, you can wrap the routes in a Route::group and apply your middleware to those routes, or individual routes respectively.
Route::middleware(['myMiddleware'])->group(function () {
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
});
Or
Route::group(['middleware' => 'myMiddleware'], function() {
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
});
Whichever is easier for you to read.
https://laravel.com/docs/5.6/routing#route-groups

Laravel sub-domain routing set global para for route() helper

I have setup sub-domain routing on my app (using Laravel 5.4) with the following web.php route:
Route::domain('{company}.myapp.localhost')->group(function () {
// Locations
Route::resource('/locations' , 'LocationController');
// Services
Route::resource('/services' , 'ServiceController');
});
However as my show and edit endpoints require an ID to be passed, using a normal route('services.show') helper results in an ErrorException stating Missing required parameters for [Route: services.create] [URI: services/create].
I appreciate this is necessary, but as the company is associated to the user on login (and is in the sub-domain) I don't want to be passing this for every view. I want to set this at a global level.
To avoid repeated queries, I thought about storing this in the session as so (in the :
protected function authenticated(Request $request, $user)
{
$current_company = $user->companies->first();
$company = [
'id' => $current_company->id,
'name' => $current_company->name,
'display_name' => $current_company->display_name
];
$request->session()->put('company', $company);
}
Which is fine, but I wonder if I can pass this to the route as a middleware or something. What's be best solution here?
Recommendation: remove the slash before the resource name.
The resource method will produce the following URIs:
/services/{service}
So, you should define your routes like this:
Route::domain('{company}.myapp.localhost')->group(function () {
// Locations
Route::resource('locations' , 'LocationController');
// Services
Route::resource('services' , 'ServiceController', ['only' => ['index', 'store']]);
Route::get('services');
});
I ran into this exact issue today, I poked around in the source and found a defaults method on the url generator that allows you to set global default route parameters like so:
app('url')->defaults(['yourGlobalRouteParameter' => $value]);
This will merge in whatever value(s) you specify into the global default parameters for the route url generator to use.

Call to undefined method Illuminate\Routing\ResourceRegistrar::addResourceEmployee()

I have this route:
Route::get('/', function () {
return view('index');
});
Route::resource('admin', 'EmployeeController');
I have model Employee and EmployeeController( with empty resource methods)
Error : Call to undefined method Illuminate\Routing\ResourceRegistrar::addResourceEmployee()
What is wrong with my code? I have used the same approach in other project and it worked.
Route::resource('admin', 'EmployeeController');
is attempting to bind to a model named Admin.
Route::resource('employees', 'EmployeeController');
should work with the model you have. To make it work with admin, name the resource parameter.
Route::resource('admin', 'EmployeeController', ['parameters' => [
'admin' => 'employee'
]]);
edit
Did you reference something outside the Laravel docs to use AddResourceEmployee(). Seems like a custom solution to me.
https://stackoverflow.com/a/16661564/320487

How to add dynamically prefix to routes?

In session i set default language code for example de. And now i want that in link i have something like this: www.something.com/de/something.
Problem is that i cant access session in routes. Any suggestion how can i do this?
$langs = Languages::getLangCode();
if (in_array($lang, $langs)) {
Session::put('locale', $lang);
return redirect::back();
}
return;
Route::get('blog/articles', 'StandardUser\UserBlogController#AllArticles');
So i need to pass to route as prefix this locale session.
If you want to generate a link to your routes with the code of the current language, then you need to create routes group with a dynamic prefix like this:
Example in Laravel 5.7:
Route::prefix(app()->getLocale())->group(function () {
Route::get('/', function () {
return route('index');
})->name('index');
Route::get('/post/{id}', function ($id) {
return route('post', ['id' => $id]);
})->name('post');
});
When you use named routes, URLs to route with current language code will be automatically generated.
Example links:
http://website.com/en/
http://website.com/en/post/16
Note: Instead of laravel app()->getLocale() method you can use your own Languages::getLangCode() method.
If you have more questions about this topic then let me know about it.
Maybe
Route::group([
'prefix' => Languages::getLangCode()
], function () {
Route::get('/', ['as' => 'main', 'uses' => 'IndexController#index']);
});

Resources