通过CakePHP中的belongsTo表指定order参数不起作用?

时间:2013-03-24 23:17:54

标签: cakephp cakephp-2.0

即使在挖掘“Specifying order parameter through a belongsTo table in CakePHP”之后,我似乎无法在表格中订购属于另一个表格中存储的实体的条目。

基本上,我有一个有很多练习的教程模型。每个练习属于教程(当然),也属于一个练习类别。当我设置recursive = 2并找到给定的教程时,我想回到一个练习行列表,首先由ExerciseCategory.title命令,然后由Exercise.sequence_number命令。

所以这是我的问题: 我的好/坏想法是根据原始exercise_category_id来排序查询结果,如下所示:

class Exercise extends AppModel {
    public $belongsTo = array( 
        'Tutorial', 
        'ExerciseCategory' 
    );

    public $order = array( 'exercise_category_id' => 'ASC',  // <=========
                           'sequence_number' => 'ASC');      // <=========

我不明白为什么这不起作用。它生成以下SQL查询:

SELECT `Exercise`.`id`, `Exercise`.`exercise_category_id`, 
`Exercise`.`tutorial_id`, `Exercise`.`sequence_number`, 
`Exercise`.`body` 
FROM `Tutorial`.`exercises` AS `Exercise` 
WHERE `Exercise`.`tutorial_id` = (1)

基于CakePHP文档,似乎查询中应该有一个ORDER BY子句,但是没有。

我需要做什么才能获得exercise_category_id号码排序的练习行,以便按照我想要的方式对它们进行分组?

Specifying order parameter through a belongsTo table in CakePHP”建议像这样设置Exercise.php模型文件:

class Exercise extends AppModel {
    public $belongsTo = array( 
        'Tutorial', 
        'ExerciseCategory' => 
            array(
                'order' => array('ExerciseCategory.title'=>'asc', 'Exercise.sequence_number' => 'asc'))
    );

但是会产生错误的SQL查询:

SELECT `ExerciseCategory`.`id`, `ExerciseCategory`.`explanation`, 
`ExerciseCategory`.`title` 
FROM `Tutorial`.`exercise_categories` AS `ExerciseCategory` 
WHERE `ExerciseCategory`.`id` = 2 
ORDER BY `ExerciseCategory`.`title` asc, `Exercise`.`sequence_number` asc

问题(正如CakePHP帮助指出的那样)是CakePHP在查询中不包含Exercises表。

修改: 这是实际生成各种查询的代码:

$this->Tutorial->recursive = 2;
$this->Tutorial->Chapter->unbindModel(array('hasMany' => array('Tutorial')));
$this->Tutorial->Exercise->unbindModel(array('belongsTo' => array('Tutorial')));
$this->Tutorial->Section->unbindModel(array('belongsTo' => array('Tutorial')));
$tut = $this->Tutorial->findById($id);

2 个答案:

答案 0 :(得分:1)

当CakePHP生成查询以引入关联模型时,它实际上创建了完全独立的查询。因此,当您使用recursive * cringe *(或Containable * yay!*)时,您无法按关联模型进行排序,因为这些表甚至不会在查询中。

如果您需要按关联模式订购,则需要使用JOINs。这样,您将只有一个查询,并且可以以任何方式订购任何您想要的表等等。

其他有用的东西:

  1. 在您的AppModel中设置$recursive = -1;,然后忘记您曾听说过它。我保证,从长远来看,你会感谢我。请改用CakePHP's Containable Behavior。递归是很酷的,只有第一次学习才能快速理解“酷 - 你可以将模型相互关联”......但除此之外,它会导致更多问题而不是它有所帮助。如果Containable没有很好地填补那个利基,也许我们需要使用递归,但是......确实如此,所以我们不这样做:)

  2. 如果您需要有关查询问题的帮助,通常最好发布您实际使用的代码来生成它。 :)

答案 1 :(得分:0)

所以,呃,事实证明 - 我可以做我希望做的事情,但我需要将order子句放在Tutorial hasMany 字段中,而不是练习的 belongsTo 字段:

class Tutorial extends AppModel {
    public $belongsTo = array('Chapter');
    public $hasMany = array('Section', 
        'Exercise' => 
            array(
                'order' => array('Exercise.exercise_category_id'=>'asc', 'Exercise.sequence_number' => 'asc')));

这更有意义,但似乎直接与Specifying order parameter through a belongsTo table in CakePHP相矛盾(诚然,这是4年前发布的)。

我要花几天时间看看其他人是否可以在标记答案之前发布更好的方法(例如,示例代码演示如何通过相关模型中的字段进行排序,而不是按相关模型的id列排序。