简体   繁体   English

CakePHP HABTM数据未保存到数据库

[英]CakePHP HABTM data not saving to database

I have a model GenForm which has a HABTM relationship with another model PdfFile . 我有一个模型GenForm ,它与另一个模型PdfFile关系。 I use this to generate a list of checkboxes in my GenForm index view. 我使用它来生成GenForm索引视图中的复选框列表。 In the GenForm model, I added: GenForm模型中,我添加了:

public $hasAndBelongsToMany = array(
    'PdfFile' => array(
        'className' => 'PdfFile',
        'joinTable' => 'gen_forms_x_pdf_files'
    )

Here's a fragment from my GenForm index.ctp view: 这是我的GenForm index.ctp视图中的一个片段:

<?php 
echo $this->Form->input( 'PdfFile', array('label' => 'Select some PDF files', 'multiple' => 'checkbox') );
echo $this->Form->input( 'first_name' );
echo $this->Form->input( 'last_name' );
?>

In the controller, I have a basic save: 在控制器中,我有一个基本保存:

    if ($this->request->is('post')) { // form was submitted
        $this->GenForm->create();
        if ($this->GenForm->save($this->request->data)) {
            return $this->redirect(array('action' => 'generate', $this->GenForm->id)); // assemble the PDF for this record
        } else {
            $this->Session->setFlash(__('Log entry not saved.'));
        }
    }

Now $this->data looks something like this when I debug() it: 现在,当我debug()它时, $this->data看起来像这样:

array(
    'PdfFile' => array(
        'PdfFile' => array(
            (int) 0 => '1',
            (int) 1 => '5'
        )
    ),
    'GenForm' => array(
        'first_name' => 'xxx',
        'last_name' => 'xxx',
        'association_id' => '1',
        'email' => ''
    )
)

Everything works perfectly, but I couldn't validate the checkboxes (at least one must be checked). 一切都很完美,但我无法验证复选框(必须至少检查一个)。 So, as per this answer , I made some changes. 所以,根据这个答案 ,我做了一些改变。

The index.ctp view became: index.ctp视图变为:

<?php 
echo $this->Form->input( 'GenForm.PdfFile', array('label' => 'Select some PDF files', 'multiple' => 'checkbox') );
echo $this->Form->input( 'first_name' );
echo $this->Form->input( 'last_name' );
?>

Here's my validation rule: 这是我的验证规则:

public $validate = array(
    'PdfFile' => array(
        'rule' => array(
            'multiple', array('min' => 1)
        ), 
        'message' => 'Please select one or more PDFs'
    )
)

This is what $this->data looks like now: 这就是$this->data现在的样子:

array(
    'GenForm' => array(
        'PdfFile' => array(
            (int) 0 => '1',
            (int) 1 => '5'
        ),
        'first_name' => 'xxx',
        'last_name' => 'xxx',
        'association_id' => '1',
        'email' => ''
    )
)

Now the checkboxes for PdfFile validate, but the PdfFile data isn't saved -- although the other fields for GenForm are saved correctly to their own table. 现在PdfFile的复选框验证,但PdfFile数据未保存 - 尽管GenForm的其他字段已正确保存到自己的表中。

Can anyone tell me what I'm missing so that PdfFile saves automatically and gets validated? 任何人都可以告诉我我缺少什么,以便PdfFile自动保存获得验证?

The first form is right 第一种形式是对的

Stating the obvious, but the form that worked is the form to use ie: 陈述显而易见的,但有效的形式是使用的形式,即:

echo $this->Form->input('PdfFile', array(
    'label' => 'Select some PDF files', 
    'multiple' => 'checkbox'
));

Changing the form to have a "field" named 'PdfFile' will simply not work - as the model layer will remove any data for fields that don't exist - and in this form it will check for gen_forms.PdfFile , find there is no field and ignore the data. 将表单更改为具有名为“PdfFile”的“字段”将无法正常工作 - 因为模型层将删除不存在的字段的任何数据 - 并且在此表单中它将检查gen_forms.PdfFile ,发现没有字段并忽略数据。

Validation 验证

To take care of validation errors - use a validation rule running on the model which checks the number of habtm records to be saved. 要处理验证错误 - 使用在模型上运行的验证规则来检查要保存的habtm记录的数量。 It doesn't matter what the name of the field used for validation is eg: 用于验证的字段的名称是什么并不重要,例如:

<?php
class GenForm extends AppModel {

    public $validate = array(
        'dummy' => array( // <- name this whatever you like
            'atLeastOne' => array(
                'required' => true, // run always
                'rule' => array('validateAtLeastOne')
            )
        )
    );

    function validateAtLeastOne() {
        if (!isset($this->data['PdfFile'])) {
            // there is no pdf data at all, ignore this rule
            // allow other save operations to work
            return true;
        }

        $return = count(array_filter($this->data['PdfFile']['PdfFile']));
        if (!$return) {
            $this->PdfFile->invalidate('PdfFile', 'Please upload a file');
        }
        return $return;
    }

}

Because the validation rule returns false if there are no records it will halt the save. 因为验证规则如果没有记录则返回false,它将停止保存。 By calling invalidate on the HABTM association with the same "field" name that the form helper will look for - an error message will be displayed. 通过使用表单助手将查找的相同“字段”名称调用HABTM关联上的invalidate,将显示错误消息。

Alternatively 另外

You can use the second approach in the question: 您可以在问题中使用第二种方法:

echo $this->Form->input('GenForm.PdfFile', array(
    'label' => 'Select some PDF files', 
    'multiple' => 'checkbox'
));

In the full knowledge that this is not how cake expects to receive data and then manipulate it to be the right format in beforeValidate: 完全知道这不是蛋糕期望接收数据然后将其操作为beforeValidate中的正确格式:

<?php
class GenForm extends AppModel {

    public $validate = array(
        'PdfFile' => array( // existing rule
            ...
        )
    );

    function beforeValidate() {
        if (isset($this->data[$this->alias]['PdfFile'])) {
            // keep the existing data as that's what validation will check against
            // copy to the right location so Cake will process it
            $this->data['PdfFile']['PdfFile'] = $this->data[$this->alias]['PdfFile'];
        }
        return true;
    }

    ...
}

If I remember correctly, from cake manual probably you are formatting the data wrongly. 如果我没记错的话,从蛋糕手册中可能你错误​​地格式化了数据。

Try that $this->data looks like this: 试试$this->data看起来像这样:

array(
    'GenForm' => array(
        'first_name' => 'xxx',
        'last_name' => 'xxx',
        'association_id' => '1',
        'email' => ''
    ),
    'PdfFile' => array(
        (int) 0 => '1',
        (int) 1 => '5'
    ),
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM