2

Containable を使用して、関連付けられたいくつかのモデル (およびそれらのデータ配列) を含むモデルを返そうとしています。モデルはテスト結果を扱います。モデルは次のとおりです。

モデル:

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

すべての AttemptedQuestions とそれに対応する Quesions + Categoryを含む Attempt を返したい

基本的に、関係は次のようにマッピングされます。

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

HABTM 関係のために、Cake は次のような復帰を望んでいると思われます。

Attempt => AttemptedQuestion(s) => array( Question, Category )<-- カテゴリは Question 配列に含まれていませんが、姉妹です。これでもいいです。

現時点では、カテゴリをまったく表示できません。コントローラー内で行っていることは次のとおりです (結果にカテゴリが表示されるわけではありません)。

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

私は何を間違っていますか?

更新 @nunser からの回答に基づくリビジョンです。これも機能しません。

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

返されるデータは次のようになります。

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',
                ...
            )
        )

    )
)

更新 2

私はまだこれに苦労していますが、次のようにすべてのカテゴリのリストが期待どおりに返されるため、関連付けは正しい必要があると思います。

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

アップデート 3

$this->Question->find('first')コード全体のさまざまなポイントからの結果をテストすることで、この問題の範囲を絞り込みました。結果は、この後まで期待されるようです: $test = $this->Test->findById($test_id);

これを示すコードは次のとおりです。

    $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

そのため、私が完全に理解していない理由により、介在することでTest->find()、後でカテゴリ データが表示されないように思われます。変でしょ?

4

4 に答える 4

1

時々、私の側では、動作の代わりにネストされたbinModelを使用する方が良い場合があります。原因はより構成可能です。このリンクを確認してください。おそらくあなたの質問に役立つでしょう

CakePHP - 複雑なクエリの構築

cakephp 1つの結合テーブルで一度に2つ以上のテーブルに結合する

于 2013-06-05T16:26:21.267 に答える
1

HABTM頭痛

これらを Cake で管理するのは困難です。私が始めたのは「hasMany Threw」と呼ばれるもので、こちらの本に記載されています

利点は、検索クエリをより細かく制御できることです。追加する必要がありModelますが、それだけの価値があります。CakePHP での HABTM の自動処理は、理解しにくいことがよくあります。関連を明示的に定義するために関連付けを使用すると、より柔軟になります。

循環参照

モデルは現在循環参照でセットアップされており、これは HABTM にとって問題になる可能性があります。

Question : has and belongs to many Category
Category : has and belongs to many Question

Cake で両方のモデルに HABTM を作成するのは非常に困難です。通常、これはそのうちの 1 つでのみ行われ、私はQuestion. 「hasMany Throw」を使用すると、より簡単になります。

ハズメニー スロー

「hasMany Threw」を使用すると、包含可能なルールの説明がはるかに簡単になります。

Question : hasMany QuestionCategory
Category : hasMany QuestionCategory
QuestionCategory : belongs to Question, belongs to Category.
Attempt : belongs to Question

今、私は削除しましAttamptedQuestionた。何をモデル化しようとしているのか正確にはわかりませんが、質問ごとに複数の試行を作成できる場合は必要ありません。複数の Attempt レコードを作成するだけです。

試行のすべてのレコードを検索

Attempt検索を使用して関連するすべてのレコードをContainable検索するには、次のようにします。

$this->Attempt->find('first',array(
    'conditions'=>array('Attempt.id'=>$attempt_id),
    'contain'=>array(
        'Question'=>array(
            'QuestionCategory'=>array(
                'Category'=>array()
            )
        )
    ));

モデルを再度追加して、AttemptedQuestion前に含めることができQuestionます。

関連のあるあいまいなフィールド名

Attempt.idだけではなく、条件で使用する習慣を身に付ける必要がありidます。関連付けを使用すると、SQL の結果にフィールド名が重複することがよくあります。if aが使用されている場合もQuestion.id条件として持つことができるため、参照しているものを明確にする必要があります。それ自体があいまいです。AttemptJOINid

于 2013-06-05T19:56:23.963 に答える
0

試す

$this->Attempt->find('first', array('conditions'=>array('id'=>$attempt_id),
                                'contain'=>array('AttemptedQuestion'=> 
                                               array('Question' => 
                                                  array('Category')
                                               )
                                )));
于 2013-06-05T16:22:55.023 に答える