我建议在模型而不是控制器中执行此操作 – 无论您从何处执行保存,都会发生这种情况.
对于日期字段问题,在模型中,覆盖save()方法并处理将数据中的多个字段转换为一个日期字段,然后再调用parent :: save进行实际保存.任何高级操作都可能发生在那里
您在评论中描述的使用隐藏表单字段来获取错误消息以显示声音的技术非常好.
为了比较两个电子邮件字段是否相等,我建议您定义一个自定义验证器.您可以使用Validator::add在引导程序中执行此操作.
use lithium\util\Validator;
use InvalidArgumentException;
Validator::add('match', function($value, $format = null, array $options = array()) {
$options += array(
'against' => '',
'values' => array()
);
extract($options);
if (array_key_exists($against, $values)) {
return $values[$against] == $value;
}
return false;
});
然后在你的模型中:
public $validates = array(
"email" => array(
"match",
"message" => "Please re-type your email address.",
"against" => "email2"
)
);
编辑:根据评论,这是一种在控制器中进行自定义规则验证的方法:
public function save() {
$entity = MyModel::create($this->request->data);
$rules = array(
"email" => array(
"match",
"message" => "Please re-type your email address.",
"against" => "email2"
)
);
if (!$entity->validates($rules)) {
return compact('entity');
}
// if your model defines a `$_schema` and sets `$_meta = array('locked' => true)`
// then any fields not in the schema will not be saved to the db
// here's another way using the `'whitelist'` param
$blacklist = array('email2', 'some', 'other', 'fields');
$whitelist = array_keys($entity->data());
$whitelist = array_diff($whitelist, $blacklist);
if ($entity->save(null, compact('whitelist'))) {
$this->redirect(
array("Controller::view", "args" => array($entity->_id)),
array('exit' => true)
);
}
return compact('entity');
}
将数据设置为实体的一个优点是,如果存在验证错误,它将自动预填充在您的表单中.