laravel

how to if roles in routes/web to determine which controller should handle?


I have a bunch of roles. my task is to determine which controller should handle based on their role. Say, I've loged in then redirect to /dashoard.

now, to handle this uri, I want it to be different controller. say, there is AdminController and SuperAdminController in web.php.

so far, i've tried like this :

if(Auth::user()->role_id == 1){
            Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('dashboard');
        }else{
            Route::get('/dashboard', [SuperAdminController::class, 'dashboard'])->name('dashboard');
            Route::get('/menu-management', [SuperAdminController::class, 'menuManagement'])->name('menu_management');
            Route::post('/change-role', [SuperAdminController::class, 'changeRole'])->name('change_role');
        }

of course this doesn't work, because auth data is null. But my question is, how to achieve this? is there any approach ti this?

Btw, I use jetsream for starter user management. thank you in advance.

EDIT: I have been read article here and there, and this is what I get so far.

in web.php :

Route::group(['middleware'=>['usercheckrole:1']], function(){
        Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('dashboard');
    });

    Route::group(['middleware'=>['usercheckrole:2']], function(){
        Route::get('/dashboard', [PharmaController::class, 'dashboard'])->name('dashboard');
    });

    Route::group(['middleware'=>['usercheckrole:3']], function(){
        Route::get('/dashboard', [ProfessionalController::class, 'dashboard'])->name('dashboard');
    });

usercheckrole middleware:

public function handle(Request $request, Closure $next, $role): Response
    {
        if (!empty($role)) {
            if(Auth::user()->role_id == $role) {
                View::composer('*', function ($view) {
                    $role_id = Auth::user()->role_id;
                    $data_menu = DB::table('role_menus')->whereRaw('find_in_set("'.$role_id.'", role_id)')->where('is_active', true)->get();
                    $view->with('__DATA_MENU', $data_menu);
                });
                return $next($request);
            }else{
                abort(403);
            }
        }
    }

the problem is that, when login as Admin, it should handle with AdminController right? but is no. rather is handled by ProfessionalController, which the last controller of the same URI. so it'slike 'overwrite' the controller. how to prevent this?


Solution

  • You can enforce the middleware in Controller constructor like this:

    class AdminController extends Controller
    {
        public function __construct()
        {
            $this->middleware('usercheckrole:1');
        }
    }
    

    Don't forget to register in Kernel.php your middleware in the section of $routeMiddleware.

    Edit to solve:

    What you have at the moment, is not possible to have same route to many controllers, it will re-write to the last. To have the same url dashboard for all roles, just have a main DashboardController@index with all logic from AdminController,PharmaController,ProfessionalController with the dashboard() logic by the $user->role_id and maybe you could reuse some code.