Сохраняйте данные сразу в одной и той же ассоциации

Я знаю, что этот вопрос задают здесь много раз, но я также пытался следовать решениям, предоставленным в моих силах. По мере того, как я изучал CakePHP, некоторые решения казалось сложным для реализации в коде. Я использую CakePHP 2.5.

Я пытаюсь создать отчет о проблеме с одной или несколькими добавленными загрузками. Вот кое-что из того, что я реализовал до сих пор:

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

  • кандидат
  • CandidatesProblemReport
  • CandidatesProblemReportsUpload

Есть ассоциации:

  • КандидатыПроблемаСообщение имеет много КандидатовПроблемаРепортыЗагрузить

  • Кандидат имеет много кандидатовПроблема отчета

  • КандидатыПроблема отчета принадлежит кандидату

  • КандидатыПроблемаРепортыЗагрузка принадлежит КандидатамПроблемаРепорт

Candidate.php

    <?php

class Candidate extends AppModel {

public $name = 'Candidate';
public $hasMany = array(

'CandidatesProblemReport' => array(
'className' => 'CandidatesProblemReport',
'foreignKey' => 'candidate_id'
)

);
}

CandidatesProblemReport.php

    <?php

class CandidatesProblemReport extends AppModel {

public $name = "CandidatesProblemReport";
public $belongsTo = array(
'Candidate' => array(
'className' => 'Candidate'
)
);
public $hasMany = array(
'Uploads' => array(
'className' => 'CandidatesProblemReportsUpload'
),
'Replies' => array(
'className' => 'CandidatesProblemReportsReply'
)
);
}

CandidatesProblemReportsController.php

    class CandidatesProblemReportsController extends AppController {

public $name = "CandidatesProblemReports";

// ############# Report a Problem #############
// ********************************************
public function create() {
$userid = $this->Auth->user('id'); // Grabs the current user id
$this->set('userId', $userid); // Sends the current user id to the form

if ($this->request->is('post') && !empty($this->request->data)):

$this->CandidatesProblemReport->create();

$report = $this->CandidatesProblemReport->save($this->request->data);
if (!empty($report)):
$this->request->data['CandidatesProblemReportsUpload']['candidates_problem_report_id'] = $this->CandidatesProblemReport->id;
endif;

if ($this->CandidatesProblemReport->saveAssociated($this->request->data)):

$this->Session->setFlash('Your report has been submitted '
. 'successfully. Thank you!');

$this->redirect(array(
'action' => 'viewall')
);
else:
$this->Session->setFlash('Your report could not be submitted, '
. 'please try again');
endif;

endif;
}
}

create.ctp

<h1>Create a report</h1>
<?php
echo $this->Form->create('CandidatesProblemReport', array('type' => 'file'));

echo $this->Form->input('CandidatesProblemReport.report_subject');

echo $this->Form->input('CandidatesProblemReport.report_handle_department', array(
'options' => array(
'Technical' => 'Technical',
'Sales' => 'Sales',
'Support' => 'Support',
'Other' => 'Other'
)
));
echo $this->Form->input('CandidatesProblemReport.report_description');

echo $this->Form->input('CandidatesProblemReport.report_date', array(
'type' => 'hidden',
'value' => date('Y-m-d H:i:s'))
);

echo $this->Form->input('CandidatesProblemReport.candidate_id', array(
'type' => 'hidden',
'value' => $userId)
);
?>

<div>
<p><strong>Upload Screenshot/Files</strong></p>
<hr>
</div>
<?php
echo $this->Form->input('CandidatesProblemReportsUpload.0.report_upload', array(
'type' => 'file'
));
?>
<button class="add-new-upload" type="button">Add more</button>
<?php
echo $this->Form->end('submit');

echo $this->Html->script('jquery-2.1.1.min.js');
?>

<script type="text/javascript">
var i = 1;
$('.add-new-upload').click(function () {
$('.file').append('<input type="file" name="data[CandidatesProblemReportsUpload]['
+ i +
'][report_upload]" id="CandidatesProblemReportsUpload'
+ i +
'ReportUpload">');
i++;
});
</script>

Теперь происходит то, что я могу сохранить основные данные модели, т.е. CandidatesProblemReports, но когда я сохраняю связанные данные, он снова сохраняет основную модель, создавая вторую дублирующую запись, но загрузки не сохраняются.

3

Решение

Сохранение данных с ассоциациями

Это ожидаемое поведение, saveAssociated() Он предназначен не только для сохранения связанных записей, но и для основной записи, поэтому вам следует использовать saveAssociated() только, не нужно вручную устанавливать внешний ключ и т. д., CakePHP сделает это автоматически.

контроллер

public function create() {
// ...

if ($this->request->is('post') && !empty($this->request->data)):

$this->CandidatesProblemReport->create();

if ($this->CandidatesProblemReport->saveAssociated($this->request->data)):
// ...
endif;

endif;
}

Следите за своими псевдонимами

Причина того, что ваши загружаемые записи не создаются, заключается в том, что вы не используете правильный псевдоним в своей форме / данных, вы установили псевдоним как Uploads, но в вашей форме вы используете CandidatesProblemReportsUploadи поэтому CakePHP будет игнорировать эти данные.

форма

echo $this->Form->input('Uploads.0.report_upload', array(
'type' => 'file'
));
<script type="text/javascript">
var i = 1;
$('.add-new-upload').click(function () {
$('.file').append('<input type="file" name="data[Uploads]['
+ i +
'][report_upload]" id="Uploads'
+ i +
'ReportUpload">');
i++;
});
</script>

Хранение данных файла

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

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

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

Для начинающих:

0

Другие решения

Других решений пока нет …