Multiple scoping resource route - laravel

i was create route resource and i use {post:slug} for route model binding but in some method for example update method, i want to use {post:id} for route model binding and keep the other method to use {post:slug}
How to implement it? Is it possible to add multiple scope
this is my code
Route::resource('/dashboard/posts', DashboardPostController::class)->scoped(['post' => 'slug']);

First, you need to use resources without update:
Route::resource('/dashboard/posts', DashboardPostController::class)->scoped(['post', 'slug'])->except('update');
and then:
Route::put('dashboard/posts/{posts:id}, [ DashboardPostController::class => 'update');

Related

Laravel edit controller not having data

I am trying to make crud in laravel. While doing dd of data variable in edit function attributes array is getting null
Route
Route::resource('/gameSettings', GameSettingController::class);
Controller
public function edit(GameSetting $game_setting)
{
dd($game_settings);
return view('admin.game_setting.edit', compact('game_setting'));
}
Model
class GameSetting extends Model
{
use HasFactory;
protected $fillable = [
'coin_value',
'minimum_withdraw_amount'
];
}
Link
https://localhost:8000/admin/gameSettings/1/edit
dd($game_settings); giving null array attribute
I dont have enough rep to comment so I give an answer...
#lagbox is correct. Your route parameter should match exactly as the variable typehinted in the controller for your case change $game_setting to $gameSetting
if you want to use $game_setting change your route to
Route::resource('/gameSettings', GameSettingController::class, ['parameters' => ['gameSetting' => 'game_setting']]);
The variable that you have typehinted on the Controller method must match exactly the name of the route parameter you have defined. In this case the parameter would be named gameSetting most likely. If you don't match these then you have Dependency Injection happening which would give you a new, non-existing, instance of the model. If you match the name then you will get Route Model Binding and it will look up the model and give you that particular entity.
If you want to see what the route parameter is named, since you are using resource routing, you can run php artisan route:list from the command line and it will show you those 7 routes and how they are defined.

Change default URL param name when using Route::resource

When using Route::resource(), Laravel of course 'chooses' somethings for you, such as route names and methods.
I know how to override, for example, the allowed routes/methods:
Route::resource('user', 'UserController', array('only' => array('index', 'show')));
But I now need to override the URL param name that Laravel sets for the user routes. By default, in the example above, it will be user. But, I want it to be user_id.
Does Laravel provide a way to set this, when using Route::resource?
So that, for example, I would end up with the route:
mydomain.com/users/{user_id}
rather than:
mydomain.com/users/{user}
Thanks
Found it. Yes, Laravel does provide a way to override this when using Route::resource().
Route::resource('users', 'UserController')->parameters([
'users' => 'user_id'
]);
The key of the element in the array in the argument to 'parameters' is the same as what you enter as the first argument of the 'resource' method (not the 'singular' version or something)

Laravel - route model binding with request headers

I am wondering is it possible to do something similar to route model binding, but with request headers. I have a query that I check on my api endpoints, that looks like this:
User::where('telephone', $request->header('x-user'))->firstOrFail();
Is it possible to somehow avoid repeating this query in every method in controllers, but to apply it to routes, so that I could just get the user object just like in a route model binding with type hinting in a function, for every route that in an api routes folder:
public function userTransactions(User $user)
{
//
}
Create a middleware and assign it to the desired routes.
Option 1
In your middleware do:
$user = User::where('telephone', $request->header('x-user'))->firstOrFail();
request()->merge(['user_model' => $user]);
You can then request()->get('user_model') anywhere in your controller
Option 2
Start by creating a global scope class that conforms to your query. Here you'd get the header value and use that in the scope.
https://laravel.com/docs/5.5/eloquent#global-scopes
Next in the middleware, add the scope to the model using addGlobalScope
User::addGlobalScope(new HeaderScope())
Now all queries for User will have a where clause with your header value.
You can subsequently remove the scope or ignore global scopes if needed.

Route User Role Laravel 5.4

I'm very confused on this situation. I have two routes with on resource name.
Route::resource('product', 'Product\AreaManagerProductController');
Route::resource('product', 'Product\SystemAdminProductController');
I need to make it as one because I have a contextual binding.
$this->app->when(AreaManagerProductController::class)
->needs(ProductInterface::class)
->give(AreaManagerProductRepository::class);
$this->app->when(SystemAdminProductController::class)
->needs(ProductInterface::class)
->give(SystemAdminProductRepository::class);
The contextual binding works fine... but I need to change my route like this.
Route::resource('product_area_manager', 'Product\AreaManagerProductController');
Route::resource('product_system_admin', 'Product\SystemAdminProductController');
I created ProductController and some kind of weird solution.
public function index(){
//Create a conditional statement base on user
return app('App\Http\Controllers\Product\AreaManagerProductController')->index();
}
It may work but it doesn't trigger the middleware... What could be the best practice on this situation. TY
You can have your Route like this
Route::group(['prefix' => 'product', 'namespace' => 'Product', 'middleware' => '<your middleware>'], function() {
Route::resource('area_manager', 'AreaManagerController');
Route::resource('system_admin', 'SystemAdminController');
});
The reason I grouped the route is to reduce redundancy, and the reason i removed Product from the controller name is, as there is a namespace Product already, there is no need of long Class names.
If you wan to access some methods in the AreaManagerController and SystemAdminController just extend the ProductController to these Controllers.
If you want to add some specific middleware for the actions inside these controllers, I have added a middleware clause in the route group which will affect to these controllers, if not needed just remove it.
Hope this helps you.

How do I set dynamic prefixes in Laravel routes

heres the situation - I'm building a site thats region based and I need to set it up so that the first segment of the route is a region i.e. of the type:
www.mysite.com/{region}
Currently I have routes set up like this:
www.mysite.com/businesses
www.mysite.com/businesses/show
I've tried a number of tricks but for some reason I can't get this to work:
www.mysite.com/{region}/businesses
in such a way that I need to filter by the {region} variable and that the {region} variable has to prepend every url in the site, also the {region} variable should also be accessible in the controller. I had a look at the localization options except I don't want to change languages here. I'm looking for implementing something of the following:
www.mysite.com/barcelona/businesses
www.mysite.com/new-york/businesses
I already have a table of all regions and slugs and the required relationships. Just trying to get this to work.
Add the region route on top of all other routes, I have similar feature for a project and that fixed it for me.
Route::get('{region?}/businesses', array(
'as' => 'regionBusinesses',
'uses' => 'RegionBusinessesController#getBusinesses'
))->where('region', '.*');
In your Controller
class RegionBusinessesController extends SomeController {
public function getBusinesses($region) {
return View::make('YOUR_VIEW_NAME')->withBusinesses($this->YOUR_MODEL->FETCH_BUSINESSES_METHOD($region));
}

Resources