【问题标题】:Specifying order parameter through a belongsTo table in CakePHP not working?通过 CakePHP 中的 belongsTo 表指定订单参数不起作用?
【发布时间】:2013-03-24 23:17:54
【问题描述】:

即使在挖掘了“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 子句,但实际上没有。

我需要做什么才能获得按锻炼类别 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 没有在查询中包含练习表。

编辑: 下面是实际生成各种查询的代码:

$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);

【问题讨论】:

    标签: cakephp cakephp-2.0


    【解决方案1】:

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

    如果您需要按相关型号订购,您需要使用JOINs。这样,您将有一个查询,并且可以以任何方式对您想要的任何表进行排序......等等。

    其他有用的东西:

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

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

    【讨论】:

    • 1) (在查看了 Containable 之后,但有点简短)Containable 如何比 recursive=2 更好,并使用 Tutorial->unbindModel 修剪不需要/不需要的关联? Containable 看起来更简洁,但还有其他区别吗? 2)我以为我是(因为模型确定了查询)。等等 - 你的意思是实际调用查找?哦!我会在编辑中添加它。对不起! :)
    • @MikeTheTall - 如果您认为每次执行查询时强制记住并手动取消绑定每个关联是个好主意,那么请务必使用递归。但是如果你添加一个模型——你现在必须遍历每一个模型并解除更多绑定(或者害怕递归自动提取太多信息并给出递归导致的太常见的内存错误)。得到我的积分?递归的唯一好处是它的“自动”部分——一旦你必须开始解除绑定,你就绕过了使用它的全部要点。
    • 好的,有道理。我同意“决定我想要什么”的方法比“删除我不想要的”方法更好。大多数情况下,我很好奇 Containable 行为是否会生成更好的 SQL 查询(或更少的 SQL 查询等)
    • 嘿,你能指点我一步一步通过 JOIN 的事情吗?我看到book.cakephp.org/2.0/en/models/…,但它看起来只是用于查找的第一个“级别”(即,您不能将关联的模型连接到另一个表)。 Containable 似乎没有任何连接功能。我认为有一种方法可以在模型本身上指定一个连接字段,但我现在似乎找不到它......
    【解决方案2】:

    所以,呃,事实证明 - 我可以做我希望做的事情,但我需要将 order 子句放在教程的 hasMany 字段中而不是 em> 练习的 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 列排序)。

    【讨论】:

      猜你喜欢
      • 2015-01-07
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多