Многоуровневые модельные ассоциации в CakePHP - PullRequest
1 голос
/ 28 марта 2012

Я создаю сайт электронного обучения в 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 в моем представлении останавливается на вопросе и не тянетсоответствующий ответ (ы) на вопрос (ы).

Я исправил эту проблему, изменив основание моего действия просмотра в TestsController:

$test = $this->Test->read(null, $id);
$test['Question'] = $this->Test->Question->find('all'); //I added this line...
$this->set('test', $test);

Я добавил среднюю строкупоэтому он буквально заменяет все содержимое $ test ['Question'] вручную перед тем, как установить массив $ test для представления.

Вот результат:

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 создает только связанные массивы данных для ассоциации моделей до определенного уровня, а затем останавливается?

PS Я пытался добавить:

var $ использовании = массив ('Test', 'Question','Answer');

... наверх моего TestsController, но это не решило проблему и, похоже, не дало результата.

Должен быть лучший способ заставить CakePHPзагрузить ВСЕ соответствующие модели данных и их ассоциации ...

Ответы [ 2 ]

2 голосов
/ 28 марта 2012

Использование контейнерного поведения CakePHP: http://book.cakephp.org/1.3/view/1323/Containable

Я думаю, что для вашего конкретного случая запрос будет выглядеть так:

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

Вы также можете использовать условия, заказ и т. Д.

1 голос
/ 28 марта 2012

Я использовал рекурсивное свойство, которое, казалось, делало это.

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

Сообщает CakePHP загрузить другой уровень ассоциации, поэтому результат включает в себя не только вопрос (-ы), но и связанный с ним ответ (-ы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...