CakePHP HABTM数据未保存到数据库 [英] CakePHP HABTM data not saving to database

查看:111
本文介绍了CakePHP HABTM数据未保存到数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型 GenForm ,它与另一个模型 PdfFile 具有HABTM关系。我用它在我的 GenForm 索引视图中生成复选框列表。在 GenForm 模型中,我添加了:

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

这是我的 GenForm 索引的一部分.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');
?>

在控制器中,我有一个基本保存:

 如果( $ this-> request-> is('post')){//表单已提交
$ this-> GenForm-> create();
if($ this-> GenForm-> save($ this-> request-> data)){
return $ this-> redirect(array('action'=>'generate',$ thi s-> GenForm-> id)); //组装此记录的PDF
}否则{
$ this-> Session-> setFlash(__('未保存日志条目。'));
}
}

现在 $ this-> ; data 当我 debug()时看起来像这样:

  array(
'PdfFile'=>数组(
'PdfFile'=> array(
(int)0 =>'1',
(int)1 =>'5'

),
'GenForm'=> array(
'first_name'=>'xxx',
'last_name'=>'xxx',
'association_id'=>'1',
'email'= >>>''







一切正常,但我无法验证复选框(必须至少选中一个)。因此,根据此答案,我进行了一些更改。



index.ctp 视图变为:

 <?php 
echo $ this-> Form-> input('GenForm.PdfFile',array('label'=>'选择一些PDF文件', 'multiple'=>'checkbox'));
echo $ this-> Form-> input(‘first_name’);
echo $ this-> Form-> input(‘last_name’);
?>

这是我的验证规则:

  public $ validate = array(
'PdfFile'=> array(
'rule'=> array(
'multiple',array('min '=> 1)
),
'消息'=>'请选择一个或多个PDF'


这就是 $ this->数据现在的样子:

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


现在 PdfFile 的复选框有效,但 PdfFile 数据不会保存-尽管 GenForm 的其他字段正确保存到了自己的表中。 / p>

谁能告诉我我所缺少的内容,以便 PdfFile 自动保存

解决方案

第一种形式是正确的


陈述明显,但该形式起作用的是使用的表单,即:

  echo $ this-> Form-> input('PdfFile',array(
'标签'=> ‘选择一些PDF文件’,
‘多个’=> 复选框
));

将表格更改为具有字段名为 PdfFile的文件将根本无法工作-因为模型层将删除不存在的字段的任何数据-并以这种形式检查 gen_forms.PdfFile ,找到没有字段并忽略数据。


验证


要处理验证错误,请在运行模型的验证规则上进行检查要保存的habtm记录数。验证所用字段的名称无关紧要,例如:

  <?php 
类GenForm扩展了AppModel {

public $ validate = array(
'dummy'=> array(//<-随意命名
'atLeastOne'=> array(
'required'=> true,//始终运行
'rule'=> array('validateAtLeastOne')


);

函数validateAtLeastOne(){
if(!isset($ this-> data ['PdfFile'])){
//根本没有pdf数据,忽略此规则
//允许其他保存操作运行
返回true;
}

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

}

因为没有记录,验证规则将返回false它将停止保存。通过在具有相同字段的HABTM关联上调用无效,从而使HABTM关联无效。表单帮助程序将查找的名称-将显示一条错误消息。


或者


您可以在问题中使用第二种方法:

  echo $ this-> Form-> input('GenForm.PdfFile',array(
'label'=>'选择一些PDF文件',
'multiple'=>'checkbox'
));

完全不知道这是不是蛋糕如何期望接收数据然后进行操作成为beforeValidate中正确的格式:

 <?php 
类GenForm扩展了AppModel {

public $ validate = array(
'PdfFile'=> array(//现有规则
...

);

函数beforeValidate(){
if(isset($ this-> data [$ this-&alia; alias ['PdfFile'])){
//保持现有数据,因为这就是验证将对照
//复制到正确位置的内容,因此Cake将对其进行处理
$ this-> data ['PdfFile'] ['PdfFile'] = $ this- > data [$ this-> alias] ['PdfFile'];
}
返回true;
}

...
}


I have a model GenForm which has a HABTM relationship with another model PdfFile. I use this to generate a list of checkboxes in my GenForm index view. In the GenForm model, I added:

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

Here's a fragment from my GenForm index.ctp view:

<?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:

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:

<?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:

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.

Can anyone tell me what I'm missing so that PdfFile saves automatically and gets validated?

解决方案

The first form is right

Stating the obvious, but the form that worked is the form to use i.e.:

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.

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. It doesn't matter what the name of the field used for validation is e.g.:

<?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. 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.

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:

<?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;
    }

    ...
}

这篇关于CakePHP HABTM数据未保存到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆