Cakephp - Сохранение связанных моделей

У меня есть следующие отношения между моими моделями:

Assignment hasMany Question
Question belongsTo Assignment
Question hasMany Answer
Answer belongsTo Question

Я хотел бы иметь единую форму, в которой можно сохранять задание, вопросы и ответы.

Форма почти рабочая, сохраняет информацию о задании и вопросы, но не ответы.

Назначения Контроллер Создать действие:

function create() {
        if (!empty($this->data)) {

        var_dump($this->data);

        unset($this->Assignment->Question->validate['assignment_id']);
        unset($this->Assignment->Question->Answer->validate['question_id']);
        $this->Assignment->saveAll($this->data, array('validate' => 'first'));
    }
}

создать.ctp

Create new assignment
<?php

echo $this->Form->create('assignment', array('action' => 'create'));
echo $this->Form->input('Assignment.title');
echo $this->Form->input('Assignment.type');
echo $this->Form->input('Question.0.question');
echo $this->Form->input('Question.0.Answer.0.answer');
echo $this->Form->end('Create');

?>

person AlexBrand    schedule 30.07.2011    source источник
comment
предположение возможно, у Cake возникают проблемы с сохранением в 3 разные модели одновременно. Для проверки разделите творение assignment и просто создайте question и answers. Если это работает как задумано, вы можете продолжить отладку, но если нет, проблема может заключаться в другом.   -  person Ross    schedule 30.07.2011
comment
может быть потому, что у меня нет прямой связи между Заданием и Ответом?   -  person AlexBrand    schedule 30.07.2011
comment
Это определенная возможность и имеет смысл. Я не уверен в обходном пути, или если это действительно так.   -  person Ross    schedule 30.07.2011
comment
Не по теме, если на вопрос есть много ответов, какая модель будет использоваться для ответов на вопрос при выполнении задания?   -  person Martin Bean    schedule 14.08.2014


Ответы (2)


Может быть, потому, что:

Assignment hasMany Question

Но Задание не имеет ответа.

Если вы найдете ('все') в назначении с правильной рекурсивной опцией, будут показаны все записи о связанных моделях. Но при создании нового назначения будут сохранены только непосредственно связанные таблицы. И Ответ не один.

Чтобы создать новый ответ, вы либо устанавливаете связь между Заданием и Ответом, либо создаете функцию для создания ответа после сохранения созданного Задания.

Вы можете на tasks_controller.php

function create() {
    $this->Assignment->saveAll($this->data, array('validate' => 'first'));
    $this->loadModel('Answer');
    $data[] = array(
        'question_id' => GET_THE_ID_OF_LAST_QUESTION_INSERTED
    );
    $this->Answer->save($data);
}

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

$this->Assignment->Question->id;

Кстати... Зачем вам автоматически создавать новый ответ после создания нового задания/вопроса? Это не имеет никакого смысла.

person rlcabral    schedule 30.07.2011
comment
Под ответом я подразумеваю возможный ответ, поскольку я создаю задание с множественным выбором. - person AlexBrand; 30.07.2011
comment
Должен ли я создать связь между возможными ответами и заданием? - person AlexBrand; 30.07.2011
comment
Я понимаю. Вам не нужно создавать связь между ответами и заданием, потому что она не существует в обычных формах. Просто создайте/сохраните ответы после создания нового задания. Вы можете использовать afterSave() book.cakephp.org/view/1053/afterSave. - person rlcabral; 30.07.2011

Решил сохранить все самостоятельно.

Что вы думаете об этой возможности?

function create() {

    if (!empty($this->data)) {
        if ($this->Assignment->save($this->data)) {
            foreach($this->data['Question'] as $question) {
                $this->Question->create();
                $question['assignment_id'] = $this->Assignment->getLastInsertId();

                if($this->Question->save($question) && $failed == false) {
                    foreach ($question['Answer'] as $answer) {
                        $this->Answer->create();
                        $answer['question_id'] = $this->Question->getLastInsertId();

                        $this->Answer->save($answer);                           
                    }
                }


            }
        }   
    }

}
person AlexBrand    schedule 30.07.2011
comment
сначала вы должны проверить все данные ($this-›Assignment-›validates(), $this-›Assignment-›Question-›validates(), $this-›Assignment-›Question-›Answer-›validates()) в случае сбоя некоторых данных на полпути сохранения. И вы не должны использовать $uses или loadModel, если это действительно не нужно. - person Anh Pham; 30.07.2011
comment
есть ли способ начать транзакцию в контроллере?, в случае сбоя проверки.... - person AlexBrand; 31.07.2011
comment
торт полностью проверяется в php. И я не думаю, что вы хотите использовать транзакцию в торте, это грязно. - person Anh Pham; 31.07.2011