如何在 Mojolicous 中使用 `find` 获取完整路线?

How to fetch full route with `find` in Mojolicous?

我有注册 REST 路由的快捷方式,例如 Mojolicious::Plugin::RESTRoutes

my $r = $self->routes;
$r->add_shortcut( resource =>  \&resource );

我还有一些 under 路由来检查用户访问级别:

my $guest =  $r->under->to( "auth#check_level" );
my $user  =  $r->under->to( "auth#check_level", { required_level =>  100 } );
my $admin =  $r->under->to( "auth#check_level", { required_level =>  200 } );

当我创建资源时:

my $uResource =  $user->resource( 'users' );

我得到下一条路线:

$ myapp.pl routes
/               *                 # under for guest
/               *                 # under for user
  +/users       *       users
    +/          GET     "list_users"
    +/create    GET     "create_user"
    +/          POST    "store_user"
    +/:id       GET     "show_user"
    +/:id/edit  GET     "edit_user"
    +/:id       PUT     "update_user"
    +/:id       DELETE  "delete_user"
/               *                       # under for admin

不,我想调整其中一些以限制访问:

$guest->add_child( $user->find( 'create_user' ) );
$admin->add_child( $user->find( 'list_users'  ) );
$admin->add_child( $user->find( 'delete_user' ) );

现在我得到了这条路线:

$ myapp.pl routes
/               *                        # under for guest
  +/create      GET     "create_user"
/               *                        # under for user
  +/users       *       users
    +/          POST    "store_user"
    +/:id       GET     "show_user"
    +/:id/edit  GET     "edit_user"
    +/:id       PUT     "update_user"
/               *                        # under for admin
  +/            GET     "list_users"    
  +/:id         DELETE  "delete_user"

如您所见,只有路线的最后一部分从 user 移动到 guest/admin
因为我这里用的是$user而不是$uResource
我希望路由 +/users 也匹配
:

$ myapp.pl routes
/               *                        # under for guest
  +/users       *       users
    +/create    GET     "create_user"
/               *                        # under for user
  +/users       *       users
    +/          POST    "store_user"
    +/:id       GET     "show_user"
    +/:id/edit  GET     "edit_user"
    +/:id       PUT     "update_user"
/               *                        # under for admin
  +/users       *       users
    +/          GET     "list_users"    
    +/:id       DELETE  "delete_user"

这完全是:

$guest->any( "/users" )->add_child( $user->find( 'create_user' ) );
$admin->any( "/users" )->add_child( $user->find( 'list_users'  ) );
$admin->any( "/users" )->add_child( $user->find( 'delete_user' ) );

有没有办法自动在前面添加 /users

我只是创建了不同的快捷方式。来源:

my $r = $self->routes;
$r->add_shortcut( resource   =>  \&resource   );
$r->add_shortcut( privileged =>  \&privileged );


# Each time someone make query we setup cookie and check his access level
my $guest =  $r->under->to( "auth#check_level" );
my $user  =  $r->under->to( "auth#check_level", { required_level =>  100 } );
my $admin =  $r->under->to( "auth#check_level", { required_level =>  200 } );

$user->privileged( 'users',  CS => $guest,  LD => $admin );


sub privileged {
    my( $r, $name, %restriction ) =  @_;
    my $singular =  Lingua::EN::Inflect::PL( $name );

    # Prefix for resource
    $r =  $r->any( "/$name" )->to( "$singular#" );

    my %api =  (()
        # Order definition has not matter each part of resource has unique path
        # type       #method       #path        #action    #route name
        ,L =>  [ $r, [ "GET"    ], "/",         '#index',  "list_$name"       ]
        ,C =>  [ $r, [ "GET"    ], '/create',   '#create', "create_$singular" ]
        ,S =>  [ $r, [ "POST"   ], '/',         '#store',  "store_$singular"  ]
        ,R =>  [ $r, [ "GET"    ], '/:id',      '#show',   "show_$singular"   ]
        ,E =>  [ $r, [ "GET"    ], '/:id/edit', '#edit',   "edit_$singular"   ]
        ,U =>  [ $r, [ "PUT"    ], '/:id',      '#update', "update_$singular" ]
        ,D =>  [ $r, [ "DELETE" ], '/:id',      '#delete', "delete_$singular" ]
    );

    # CS => $guest,  REU => $user,  LD => $admin  translated into:
    # $api{ C => [ $guest ...],  S => [ $guest ... ], ..., D => [ $admin ... ] }
    for my $level ( keys %restriction ) {
        # Prefix for resource
        my $r =  $restriction{ $level }->any( "/$name" )->to( "$singular#" );

        for my $resource ( split //, $level ) {
            $api{ $resource }[0] =  $r;
        }
    }


    # Create route for all resouces: LCSREUD
    for my $resource ( keys %api ) {
        my( $guard, $method, $path, $action, $rname ) =  @{ $api{ $resource } };
        $guard->any( $method, $path, $rname )->to( $action );
    }


    return;
}

有什么建议吗?