如何将验证错误字段名称转换为CakePHP中的输入名称?

时间:2012-09-13 20:06:16

标签: cakephp

我有一个CakePHP(最新版本)Web应用程序,表单和验证都使用传统的回发正常工作,但现在我正在切换一些表单通过ajax提交。当存在验证错误时,我希望将它们作为JSON格式返回客户端,如下所示:

{
"success":false,
"errors":{
    "data[User][username]":["This is not a valid e-mail address"],
    "data[User][password]":["You must choose a password"]
}}

errors数组的键需要与表单字段上的name属性相对应。我们有一些预建的客户端脚本,期望以这种方式格式化JSON。好消息是,这与CakePHP中的validationErrors对象非常接近。所以我现在正在我的控制器中执行此操作:

if ($this->User->save($this->request->data)) {

} else {
    if ($this->request->is('ajax')) {
        $this->autoRender = $this->layout = false;
        $response['success'] = false;
        $response['errors'] = $this->User->validationErrors;
        echo json_encode($response);
        exit(0);
    }
}

但是,这就是JSON响应的样子:

{
"success":false,
"errors":{
    "username":["This is not a valid e-mail address"],
    "password":["You must choose a password"]
}}

请注意,错误键中只包含基本数据库表字段名称。它们不会转换为数据[用户] [用户名]格式,FormHelper通常会处理这些格式。

在返回数组之前是否有一些简单的方法来调整数组?我不想简单地循环并添加“数据[用户]”,因为它不够健壮。我想要一些代码,我可以放在一个地方,并从各种控制器调用各种型号。 FormHelper使用什么来提出输入名称属性?我能点进去吗?我应该以某种方式使用JSON视图吗?

3 个答案:

答案 0 :(得分:2)

那是因为这就是$validationErrors数组的格式化方式。要获得你想要的输出,你必须循环,没有办法解决它。

foreach ($this->User->validationErrors as $field => $error) {
  $this->User->validationErrors["data[User][$field]"] = $error;
  unset($this->User->validationErrors[$field]);
}

我建议将所有错误传递给json_encode()$this->validationErrors是视图上可用的所有模型验证错误的组合列表(在渲染后编译)。您应该将显示逻辑(回显json)移动到视图中,然后在那里循环显示。

视图中的

$errors = array();
foreach ($this->validationErrors as $model => $modelErrors) {
  foreach ($modelErrors as $field => $error) {
    $errors["data[$model][$field]"] = $error;
  }
}
$response['errors'] = $errors;
echo json_encode($response);

这将输出如下内容:

{
  "success":false,
  "errors": [
      "data[User][username]": "This is not a valid e-mail address",
      "data[User][password]": "This is not a valid password",
      "data[Profile][name]": "Please fill in the field"
  ]
}

答案 1 :(得分:1)

I have created a small recursive function to create validation error as a string with column name so that can be passed as json object.

 /**
     * prepare erorr message to be displayed from js
     *
     * @param array   $errors  validation error array
     * @param stringn $message refernce variable
     *
     * @return void
     */
    public function parseValidationErrors($errors, &$message)
    {
        foreach ($errors as $columnName => $error) {
            $message .= "<strong>$columnName:</strong> ";
            foreach ($error as $i => $msg) {
                if (is_array($msg)) {
                    $this->_parseValidationErrors($msg, $message);
                } else {
                    $message .= str_replace("This field", "", $msg . " ");
                    isset($error[$i + 1]) ? $message .= " and " : $message;
                }
            }
        }
    }

和控制器代码就是这样。

if (!$this->YourModel->saveAll($modelObject)) {
                $errors = $this->YourModel->validationErrors;
                $message = '';
                $this->parseValidationErrors($errors, $message);
                $response = array('status' => 'error', 'message' => $message);
            }

答案 2 :(得分:0)

$response['errors']['User'] = $this->User->validationErrors;