CakePHP:如何使用可嵌套的HABTM模型 [英] CakePHP: How to use Containable for nested HABTM models

查看:95
本文介绍了CakePHP:如何使用可嵌套的HABTM模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Containable返回一个带有多个关联模型(以及这些数据数组)的模型。模型处理测试结果。以下是型号:



型号:

 属于许多类别
类别:has和属于许多问题
尝试:有很多AttemptedQuestions
AttemptedQuestion:属于问题

我想要返回一个尝试与其所有的AttemptedQuestions和他们的相应的Quesions +类别



所以基本上,关系如下:



尝试=> AttemptedQuestion(s)=> Question =>类别



我怀疑由于HABTM关系,Cake更喜欢返回:



尝试=> AttemptedQuestion(s)=>数组(问题,类别)< - 类别不包含在问题数组,而是他们是姐妹。这也很好。



目前我无法获得类别显示。这是我在控制器内做的(这不会导致类别出现在结果中):

  $ this-> ; Attempt-> contains(array('AttemptedQuestion'=> array('Question'=>'Category'))); 
$ attempt_to_be_graded = $ this-> Attempt-> findById($ attempt_id);

我做错了什么?



更新
以下是基于@nunser答案的修订版本。这也不起作用。

  $ this-> Attempt-> contains(array('AttemptedQuestion'=> array ('Question'=> array('Question'=> array('Category'))))); 
$ attempt_to_be_graded = $ this-> Attempt-> findById($ attempt_id);

这是数据返回的样子:

  array(
'Attempt'=&array; array(
'id'=>'39',
...

'AttemptedQuestion'=> array(
(int)0 => array(
'id'=>'189',
...,
'Question'=> array(
'id'=>'165',
...

),
)1 =>数组(
'id'=>'188',
...,
'问题'=> array(
'id'=> ;'164',
...





更新2



我还在努力工作,我的关联必须是正确的,因为下面返回所有我的类别的列表,正如预期:



$ categories = $ this-> Attempt > AttemptedQuestion-> Question-> Category-> find('all');



/ strong>



通过测试 $ this-> Question-> find()的结果,我已经缩小了这个问题的范围。 'first')。看起来结果预期为UNTIL之后的结果: $ test = $ this-> Test-> findById($ test_id);



这是代码演示:

  $ this-> loadModel ; 
$ test = $ this-> Question-> find('first');
debug($ test);
//这些结果包括类别DATE

$ test = $ this-> Test-> findById($ test_id);

$ this-> loadModel('Question');
$ test = $ this-> Question-> find('first');
debug($ test);
exit;
//这些结果不包括类别DATE

因为我完全不明白,介于 Test-> find()似乎阻止类别数据之后出现。很奇怪,是吗?

解决方案

提供有关触发问题的新信息。

  $ this-> loadModel('Question'); 
$ test = $ this-> Question-> find('first');
debug($ test);
//这些结果包括类别DATE

$ test = $ this-> Test-> findById($ test_id);

$ this-> loadModel('Question');
$ test = $ this-> Question-> find('first');
debug($ test);
exit;
//这些结果不包括类别DATE

$ c> findById magic函数(这就是我所说的)调用低级数据源驱动程序来执行查询。



code> DboSource.php 它不使用 Containable 行为来控制递归,并更改递归 Model 中的code>属性。我认为这会导致 Containable 行为的麻烦。



您可以通过重置递归返回到 findById 后的默认值。

  $ test = $ this-> Test-> findById($ test_id); 
$ this-> Test-> recursive = 1;

$ this-> loadModel('Question');
$ test = $ this-> Question-> find('first');
debug($ test);
exit;

我要猜测这解决了问题,但是你必须记住在使用 findById 或任何其他魔法函数。



这应该是蛋糕开发者报告错误,如果它是可重复的。



编辑:



递归预设值不是0。

I'm trying to use Containable to return a model with several of its associated models (and those arrays of data). The models deal with test results. Here are the models:

Models:

Question : has and belongs to many Category
Category : has and belongs to many Question
Attempt : has many AttemptedQuestions
AttemptedQuestion : belongs to Question

I want to return an Attempt with all of it's AttemptedQuestions and their corresponding Quesions + Category

So basically, the relationships map like this:

Attempt => AttemptedQuestion(s) => Question => Category

I suspect that because of the HABTM relationship, Cake would prefer to return:

Attempt => AttemptedQuestion(s) => array( Question, Category ) <--Categories are not contained within the Question array, but rather they are sisters. This is fine as well.

At the moment I am unable to get Category to show up at all. Here's what I'm doing inside a controller (this does NOT result in the Categories appearing in results):

$this->Attempt->contain(array('AttemptedQuestion' => array('Question'=>'Category'))); 
$attempt_to_be_graded = $this->Attempt->findById( $attempt_id );

What am I doing wrong?

Update Here's a revision based on the answer from @nunser. This also does not work.

$this->Attempt->contain(array('AttemptedQuestion' => array('Question'=>array('Question'=>array('Category') )))); 
$attempt_to_be_graded = $this->Attempt->findById($attempt_id );

This is what the data returned looks like:

array(
    'Attempt' => array(
        'id' => '39',
        ...
    ),
    'AttemptedQuestion' => array(
        (int) 0 => array(
            'id' => '189',
            ...,
            'Question' => array(
                'id' => '165',
                ...
            )
        ),
        (int) 1 => array(
            'id' => '188',
            ...,
            'Question' => array(
                'id' => '164',
                ...
            )
        )

    )
)

Update 2

I'm still struggling with this, but I think my associations have to be correct because the following returns a list of all my Categories just as expected:

$categories = $this->Attempt->AttemptedQuestion->Question->Category->find('all');

Update 3

I've narrowed down the scope of this problem by testing the results of $this->Question->find('first') from various points throughout the code. It appears that the results are expected UNTIL after this: $test = $this->Test->findById($test_id);.

Here is the code which demonstrates:

    $this->loadModel('Question');       
    $test = $this->Question->find('first');
    debug($test);
//THESE RESULTS INCLUDE Category DATE

    $test = $this->Test->findById($test_id);

    $this->loadModel('Question');       
    $test = $this->Question->find('first');
    debug($test);
    exit;
//THESE RESULTS DO NOT INCLUDE Category DATE

So for reasons I completely do not understand, the intervening Test->find() seems to prevent the Category data from appearing afterwards. Weird, huh?

解决方案

Give the new information about what triggers the problem.

$this->loadModel('Question');       
$test = $this->Question->find('first');
debug($test);
//THESE RESULTS INCLUDE Category DATE

$test = $this->Test->findById($test_id);

$this->loadModel('Question');       
$test = $this->Question->find('first');
debug($test);
exit;
//THESE RESULTS DO NOT INCLUDE Category DATE

In the above scenario the findById magic function (that's what I call them) calls the lower level data source driver to perform the query.

In the DboSource.php it's not using the Containable behavior to control recursion, and changes the recursive property in the Model. I think this is causing the trouble with the Containable behavior.

You can fix this by reset the recursive back to it's default after the findById.

$test = $this->Test->findById($test_id);
$this->Test->recursive = 1;

$this->loadModel('Question');       
$test = $this->Question->find('first');
debug($test);
exit;

I'm going to guess this fixes the problem, but you have to remember to reset it after using findById or any other magic function.

This should be report to the Cake developers as a bug if it's reproducible.

EDIT:

recursive default is 1 not 0.

这篇关于CakePHP:如何使用可嵌套的HABTM模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆