简体   繁体   English

具有相同名称的laravel过滤器组路由

[英]laravel filter group routes with same name

I'm stuck with this annoying problem in my laravel 4 project wich has three types of users being students, teachers and moderator (I use Entrust as role management solution). 我在laravel 4项目中遇到了这个烦人的问题,该项目有三种类型的用户,即学生,教师和主持人(我使用Entrust作为角色管理解决方案)。

Each of them can browse the same route, but depending on the user type, another method should be called. 他们每个人都可以浏览相同的路线,但是根据用户类型,应调用另一种方法。 So my route.php files was structured like this: 所以我的route.php文件的结构如下:

Route::group(array('before' => 'auth'), function(){


Route::group(array('before' => 'teacher'), function(){
        Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
        Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));



});
Route::group(array('before' => 'moderator'), function(){
        Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsModerator'));
        Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsModerator'));

});     
Route::group(array('before' => 'student'), function(){

        Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsStudent'));
        Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsStudent'));




});

});

However, browsing these routes with a teacher or moderator account always returned 404 errors. 但是,使用教师或主持人帐户浏览这些路由始终会返回404错误。 I found that was because the routes were redefined in the two other filter groups. 我发现这是因为在其他两个过滤器组中重新定义了路由。

So if I would redirect a teacher user to 'showTask', laravel would return tasks as a route for students,as that's the last time the 'showTask' route was redefined, and I would get a 404 error. 因此,如果我将教师用户重定向到“ showTask”,则laravel会将任务作为学生的路由返回,因为那是最后一次重新定义“ showTask”路由,并且会出现404错误。

My question now was: what would be the best way to handle this error? 我现在的问题是:处理此错误的最佳方法是什么?

I hope this isn't too messy. 我希望这不会太混乱。 Thanks in advance! 提前致谢!

Taking from @Matthias S's answer, does this work? 取自@Matthias S的答案,这行得通吗? Instead of using the entrust filter, check the permissions for the route like this: 不要使用entrust过滤器,而是检查路由的权限,如下所示:

//routes.php
 if(Entrust::hasRole('teacher')) {
     Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
     Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));
 }

Repeat for different roles 重复不同的角色

EDIT: Also if you had the role of the user stored in a session, you could use a sort of automatic route like this: 编辑:同样,如果您在会话中存储了用户角色,则可以使用如下自动路由:

//routes.php
 if(Entrust::hasRole(Session::get('role'))) {
     Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAs'.Session::get('role')));
     Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAs'.Session::get('role')));
 }

This way you can add as many roles as you want once you add the correct controller function for the role. 这样,一旦为角色添加了正确的控制器功能,便可以根据需要添加任意数量的角色。

EDIT #2: 编辑#2:

Or I guess even better 或者我想更好

//routes.php - UPDATED, verify role inside controller instead of defining routes based on role
     Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasks'));
     Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTask'));


//TasksController.php
public function __construct(){
    if(!Session::get('role')){ //Make sure the user has a role assigned
        return Redirect::to('login'); // Redirect to login or permission screen if not
    }
}

public function tasks(){
    if(Entrust::hasRole(Session::get('role')){
        $tasks = Tasks::where('role_id', '=', $role->id); // Get tasks based on role
        View::make('tasks.index')->with('tasks', $tasks);
    } else{
        // Show permissions error for user
    }
}

public function showTask($task_id){
    if(Entrust::hasRole(Session::get('role')){
        $task = Tasks::where('role_id', '=', $role->id)->where('id', '=', $task_id)->first();
        View::make('tasks.view')->with('task', $task);
    }
}

Move the secondary routes group out of the main auth group, then use the pipe command to run auth before for each group eg 将辅助路由组移出主要身份验证组,然后使用pipe命令在每个组之前运行身份验证,例如

Route::group(array('before' => 'auth|teacher'), function(){
Route::group(array('before' => 'auth|moderator'), function(){

I am not sure if your approach is a good way to get this done. 我不确定您的方法是否是完成此任务的好方法。 I would think that defining the same routes twice is not good practice, but I have no idea if that is true. 我认为两次定义相同的路线不是一个好习惯,但是我不知道这是否是正确的。

One way to work around this could be that you define only two routes and let the controller decide which action to perform based on the role of the user. 解决此问题的一种方法可能是,您仅定义两个路由,然后让控制器根据用户的角色决定要执行的操作。 This is not a direct solution to your problem but another way of handling the issue of having different roles performing different controller actions. 这不是直接解决问题的方法,而是处理具有不同角色执行不同控制器操作的问题的另一种方法。

Route::group(array('before' => 'auth'), function(){

     Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasks'));
     Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTask'));

});

Then in your TasksController, you make the methods tasks and showTask something like this 然后在TasksController中,使方法task和showTask像这样

class TasksController extends BaseController {
  public function tasks() {
    if(Entrust::hasRole('teacher')) {
      return $this->tasksAsTeacher();
    } else if(Entrust::hasRole('moderator')) {
      return $this->tasksAsModerator();
    } else if(Entrust::hasRole('student')) {
      return $this->tasksAsStudent();
    }
  }

  public function showTask($id) {
    if(Entrust::hasRole('teacher')) {
      return $this->showTaskAsTeacher($id);
    } else if(Entrust::hasRole('moderator')) {
      return $this->showTaskAsModerator($id);
    } else if(Entrust::hasRole('student')) {
      return $this->showTaskAsStudent($id);
    }
  }
}

Just another way to do this, makes your routes cleaner and puts the logic into the controller. 这样做的另一种方法是使您的路由更整洁,并将逻辑放入控制器中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM