将数据保存在cakephp hasmany和belongssto association中

时间:2014-10-30 06:54:36

标签: php cakephp model-associations cakephp-2.5

我知道这个问题在这里被多次询问,但我也试着按照我最好的方式提供解决方案。当我学习cakephp时,一些解决方案似乎很难在代码中实现。我正在使用cakephp 2.5。

我要做的是创建附带一个或多个上传的问题报告。以下是我目前实施的一些内容: -

我有以下型号:

  • 候选
  • CandidatesProblemReport
  • CandidatesProblemReportsUpload

协会如下:

  • CandidatesProblemReport hasMany CandidatesProblemReportsUpload

  • 候选人有许多候选人问题报告

  • CandidatesProblemReport属于候选人

  • CandidatesProblemReportsUpload belongsTo CandidatesProblemReport

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,但是当我保存相关数据时,它再次保存主模型,创建第二个重复条目,但上传不会被保存。

2 个答案:

答案 0 :(得分:0)

使用关联保存数据

这是预期的行为,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,并查看文档,了解如何在保存数据之前修改数据。

首先:

答案 1 :(得分:0)

您可以使用$this->CandidatesProblemReport->saveAssociated($this->request->data)代码使用一个查询将关联数据保存到多个表中。