CakePHP 2.2.4:在路由中使用多个S ..

时间:2013-03-25 20:28:23

标签: cakephp routing routes

我没有看到涉及路线中多个slu的问题。

我有一张名为“老师”,“课程”和“科目”的表格。每个都有一个名为“快捷方式”的字段。

如何从以下网址中路由并提取正确的Teacher.id,Course.id和Subject.id:

http://www.domain.com/bowlerae/grade-5/math

其中“bowlerae”是Teacher.shortcut,“grade-5”是Course.shortcut,“math”是Subject.shortcut。

我不知道如何最初路由这个,如何提取每个3个元素的ID(我会在AppController或我需要的每个控制器中执行此操作吗?)以及如何构建与反向路由AND兼容的链接分页。另外,“快捷方式”字段是否需要为每个表创建唯一的名称,例如“teacher_slug”,“course_slug”,“subject_slug”?

现在,我正在我的routes.php中加载3个模型中的每个模型并查询以获取每个模型的相应ID(如果URL的那部分存在),然后将这些值传递给控制器​​。但是你可以想象,它花了很多资源。

其他问题/疑虑(适用于AD7six及其他人)

如果我想要这样的网址

http://www.domain.com/bowlerae

指向教师的主页,或类似这样的网址

http://www.domain.com/bowlerae/grade-5

指向课程的主页,我会有类似以下的路线

Router::connect(
    '/:teacher', 
    array('controller' => 'teachers', 'action' => 'view'),
    array(
        'teacher'   => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
        'pass' => array('teacher')
));

为教师,以及以下课程

Router::connect(
    '/:teacher/:course', 
    array('controller' => 'courses', 'action' => 'view'),
    array(
        'teacher'   => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
        'course'   => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
        'pass' => array('teacher', 'course')
));

我担心的是,如果有人导航到

这样的网址会怎么样

http://www.domain.com/account其中,帐户是有效的控制器,但不是有效的教师

http://www.domain.com/bowlerae/students学生是有效的管理员,但不是有效的课程

我将如何处理这些实例?我尝试使用像这样的重定向方法......

TeachersController.php

public function view($tSlug = null) {
    $this->Teacher->id = $this->Teacher->findByShortcut($tSlug);

    if (!$this->Teacher->exists()) {
                  $this->Session->setFlash('This teacher does not exist');
                  $this->redirect(array('controller' => $tSlug));
    }
            else{
            // do this
            } // end else if teacher exists
    } 

我希望它能够路由以下网址

http://www.domain.com/account到帐户控制器,但它将其路由到

http://www.domain.com/account/index,更正帐户控制器并更正索引操作,但它将“/ index”附加到网址末尾。

通过我的路线现在的方式,它正在尝试访问课程控制器,所以我将相同的重定向方法添加到课程控制器中,如此...

CoursesController.php

public function view($tSlug = null, $cSlug = null) {
    $this->Teacher->id = $this->Teacher->findByShortcut($tSlug);
    $this->Course->id = $this->Course->findByShortcut($cSlug);


    if (!$this->Teacher->exists()) {
                  $this->Session->setFlash('This teacher does not exist');
                  $this->redirect(array('controller' => $tSlug, 'action' => $cSlug));
    }
    elseif (!$this->Course->exists()) {
                  $this->Session->setFlash('This course does not exist');
                  $this->redirect(array('controller' => $tSlug, 'action' => $cSlug));
    }
            else{
            // do this
            } // end else if everything is fine
    } 

不幸的是,我收到错误消息称重定向永远不会结束。

另外,我已经为这样的URL创建了路径(如果没有教师,课程或主题),但可能它们不正确。

1 个答案:

答案 0 :(得分:3)

测试针对数据库的所有请求以查看它们是否与路由匹配是一个非常糟糕的主意。

将逻辑放入控制器

一种简单的方法是创建路径ala:

Router::connect('/*', array('controller' => 'x', 'action' => 'y'));

或稍微具体一点:

Router::connect(
    '/:teacher/:course/:subject', 
    array('controller' => 'x', 'action' => 'y'),
    array('pass' => array('teacher', 'course', 'subject')
);

并确保首先声明您使用的所有其他路线。然后简单地创建一个控制器动作,如下所示:

XController extends AppController {

    public $uses = array('Teacher');

    public function y($tSlug, $cSlug, $sSlug) {
        $teacher = $this->Teacher->findBySlug($tSlug);
        ...
    }

}

限制路线元素

使用route validation,您可以限制与给定路由元素匹配的内容,例如,如果只有5位教师,则可以通过确保以其slug开头来阻止任何其他URL匹配:

Router::connect(
    '/:teacher/:course/:subject', 
    array('controller' => 'x', 'action' => 'y'),
    array(
        'teacher' => 'rita|sue|bob|larry|mo',
        'pass' => array('teacher', 'course', 'subject')
);

如果您想从db - 缓存数据库查询中读取教师的slugs,请不要在路由文件中读取所有请求中的db。

在您的路线中放置固定的东西

使用没有固定字符串的路由意味着任何具有3个路径段的网址都将与路由匹配 - 在路由中放置固定内容可能不太容易出错,因此您可以确定请求实际上是对于老师,课程,科目组合

Router::connect('/anything/*', array('controller' => 'x', 'action' => 'y'));

这可以防止任何“这个网址与此路由匹配吗?”逻辑 - 就像它一样,或者它没有。