0

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

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

这是我认为的一个片段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' );
?>

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

    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.'));
        }
    }

现在$this->data看起来像这样debug()

array(
    'PdfFile' => array(
        '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' => 'Select some PDF files', '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)
        ), 
        'message' => 'Please select one or more PDFs'
    )
)

这是现在的$this->data样子:

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

现在验证的复选框PdfFile,但PdfFile数据没有保存 - 尽管其他字段GenForm正确保存到他们自己的表中。

谁能告诉我我缺少什么以便PdfFile自动保存得到验证?

4

2 回答 2

2

第一种形式是对的

说明显而易见,但有效的形式是使用的形式,即:

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

将表单更改为具有名为“PdfFile”的“字段”将根本不起作用-因为模型层将删除不存在的字段的任何数据-在此表单中它将检查gen_forms.PdfFile,发现没有字段并忽略数据。

验证

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

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

}

因为如果没有记录,验证规则将返回 false,它将停止保存。通过使用表单助手将查找的相同“字段”名称对 HABTM 关联调用 invalidate - 将显示错误消息。

或者

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

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

完全知道这不是cake 期望接收数据然后在 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;
    }

    ...
}
于 2013-08-26T15:59:43.063 回答
0

如果我没记错的话,从蛋糕手册中你可能错误地格式化了数据。

试试看$this->data起来像这样:

array(
    'GenForm' => array(
        'first_name' => 'xxx',
        'last_name' => 'xxx',
        'association_id' => '1',
        'email' => ''
    ),
    'PdfFile' => array(
        (int) 0 => '1',
        (int) 1 => '5'
    ),
)
于 2013-08-26T15:29:55.293 回答