CakePHP HABTM数据未保存到数据库 [英] CakePHP HABTM data not saving to database
问题描述
我有一个模型 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屋!