CakePHP中的多级模型关联

CakePHP中的多级模型关联,cakephp,Cakephp,我正在用CakePHP构建一个在线学习网站,它有各种模型:课程、测试、问题、答案和其他 以下是我的联想: 这门课有很多考试 考试属于课程 问题属于测试 这个问题有很多答案 回答下面的问题 此模型关联在大多数情况下都可以正常工作。例如,课程的烘焙CRUD操作知道有属于它的测试,问题知道它们有相关的答案,等等 但我正在尝试编写一个测试管理工具,该工具在TestsController中运行,关联级别在问题中结束。没有答案。换句话说,我正在处理的视图在烘焙TestsController中默认具有以下

我正在用CakePHP构建一个在线学习网站,它有各种模型:课程、测试、问题、答案和其他

以下是我的联想:

  • 这门课有很多考试
  • 考试属于课程
  • 问题属于测试
  • 这个问题有很多答案
  • 回答下面的问题
此模型关联在大多数情况下都可以正常工作。例如,课程的烘焙CRUD操作知道有属于它的测试,问题知道它们有相关的答案,等等

但我正在尝试编写一个测试管理工具,该工具在TestsController中运行,关联级别在问题中结束。没有答案。换句话说,我正在处理的视图在烘焙TestsController中默认具有以下内容:

Array
(
[Test] => Array
    (
        [id] => 1
        [name] => Test 1
        [course_id] => 1
        [time_limit] => 30
        [max_questions] => 20
        [randomize_order] => 1
        [num_questions] => 2
    )

[Course] => Array
    (
        [id] => 1
        [course_identifier] => TLE1001
        [title] => Child Development I
        [description] => 
    )

[Question] => Array
    (
        [0] => Array
            (
                [id] => 1
                [text] => What is your name?
                [test_id] => 1
                [order] => 0
            )

        [1] => Array
            (
                [id] => 2
                [text] => What is my name?
                [test_id] => 1
                [order] => 0
            )

    )

)
$test = $this->Test->read(null, $id);
$test['Question'] = $this->Test->Question->find('all'); //I added this line...
$this->set('test', $test);
正如您所看到的,我的视图中的$test数组在问题处停止,并且不会提取问题的相关答案

我通过在TestsController中更改“查看”操作的底部修复了此问题:

Array
(
[Test] => Array
    (
        [id] => 1
        [name] => Test 1
        [course_id] => 1
        [time_limit] => 30
        [max_questions] => 20
        [randomize_order] => 1
        [num_questions] => 2
    )

[Course] => Array
    (
        [id] => 1
        [course_identifier] => TLE1001
        [title] => Child Development I
        [description] => 
    )

[Question] => Array
    (
        [0] => Array
            (
                [id] => 1
                [text] => What is your name?
                [test_id] => 1
                [order] => 0
            )

        [1] => Array
            (
                [id] => 2
                [text] => What is my name?
                [test_id] => 1
                [order] => 0
            )

    )

)
$test = $this->Test->read(null, $id);
$test['Question'] = $this->Test->Question->find('all'); //I added this line...
$this->set('test', $test);
我添加了中间一行,这样它就可以在为视图设置$test数组之前手动替换$test['Question']的所有内容

结果如下:

Array
(
[Test] => Array
    (
        [id] => 1
        [name] => Test 1
        [course_id] => 1
        [time_limit] => 30
        [max_questions] => 20
        [randomize_order] => 1
        [num_questions] => 2
    )

[Course] => Array
    (
        [id] => 1
        [course_identifier] => TLE1001
        [title] => Child Development I
        [description] => The first years of life offer a window of opportunity for a child’s development. A solid understanding of how children grow and develop is essential to providing a quality care environment.
    )

[Question] => Array
    (
        [0] => Array
            (
                [Question] => Array
                    (
                        [id] => 1
                        [text] => What is your name?
                        [test_id] => 1
                        [order] => 0
                    )

                [Test] => Array
                    (
                        [id] => 1
                        [name] => Test 1
                        [course_id] => 1
                        [time_limit] => 30
                        [max_questions] => 20
                        [randomize_order] => 1
                        [num_questions] => 2
                    )

                [Answer] => Array
                    (
                        [0] => Array
                            (
                                [id] => 1
                                [question_id] => 1
                                [text] => My name is what I say it is.
                                [correct] => 1
                            )

                        [1] => Array
                            (
                                [id] => 2
                                [question_id] => 1
                                [text] => My name is Earl.
                                [correct] => 
                            )

                    )

            )

        [1] => Array
            (
                [Question] => Array
                    (
                        [id] => 2
                        [text] => What is my name?
                        [test_id] => 1
                        [order] => 0
                    )

                [Test] => Array
                    (
                        [id] => 1
                        [name] => Test 1
                        [course_id] => 1
                        [time_limit] => 30
                        [max_questions] => 20
                        [randomize_order] => 1
                        [num_questions] => 2
                    )

                [Answer] => Array
                    (
                        [0] => Array
                            (
                                [id] => 3
                                [question_id] => 2
                                [text] => None of your business
                                [correct] => 1
                            )

                        [1] => Array
                            (
                                [id] => 4
                                [question_id] => 2
                                [text] => Jim
                                [correct] => 
                            )

                    )

            )

    )

)
这对我必须完成的工作是有效的,但对我来说,这似乎很难看。正如你所看到的,答案会被加载,但我现在也有重复的信息,因为当它加载问题模型时,它会拉入相关的测试。我很确定这与CakePHP惯例不符

有更好的方法吗?CakePHP是否只为模型关联构建关联数据数组,直到某个级别,然后停止

另外,我试图补充:

var$uses=array('Test','Question','Answer')

…到我的TestsController的顶部,但它没有解决问题,似乎没有任何效果


必须有更好的方法让CakePHP加载所有关联的数据模型及其关联…

使用CakePHP的可包含行为:

我认为对于您的具体情况,查询如下所示:

$this->Test->find('all', array(
    'contain'=>array('Question')
    )
);

您还可以使用条件、排序等。

我使用了递归属性,似乎可以做到这一点

$test = $this->Test->find('all', array('recursive' => 2));

告诉CakePHP加载另一级别的关联,因此结果不仅包括问题,还包括它们的关联答案。

该查询对我来说也没有任何改变。结果$test仍然只有问题,没有答案。我查看了您发送的链接并尝试了以下操作:
$test=$this->test->find('all',array('contain'=>array('Question'=>array('Answer')))这也不起作用。我还试着把
'contain'=>array('Answer')
也放进去,但没有用。错误是什么?此外,这取决于您的CakePHP版本-在一些早期版本中,您可能需要显式添加Containable behavior.Yup,这也可以做到。对于大型查询和大量记录,它的效率会有点低,因为它可以有效地获取所有信息,但对于小型查询,它应该可以。