【发布时间】:2016-09-27 18:48:35
【问题描述】:
我想为 ActiveRecord 应用验证器,但不为特定字段应用验证器,我的意思是,我想在表单的错误摘要中看到验证器,但不关联到特定字段。
【问题讨论】:
-
你能说得更具体一点,举个例子吗?我猜您正在寻找的是覆盖验证方法,但如果没有更多信息很难说。
标签: validation activerecord yii2
我想为 ActiveRecord 应用验证器,但不为特定字段应用验证器,我的意思是,我想在表单的错误摘要中看到验证器,但不关联到特定字段。
【问题讨论】:
标签: validation activerecord yii2
编写自定义验证时,需要使用yii\base\Model(如果在模型中编写)或yii\validators\Validator(如果编写单独的验证器)的addError方法。
这两种方法都需要传递$attribute参数(属性名),从源码可以看出,不能留空:
addError 的yii\base\Model:
/**
* Adds a new error to the specified attribute.
* @param string $attribute attribute name
* @param string $error new error message
*/
public function addError($attribute, $error = '')
{
$this->_errors[$attribute][] = $error;
}
addError 的yii\validators\Validator:
/**
* Adds an error about the specified attribute to the model object.
* This is a helper method that performs message selection and internationalization.
* @param \yii\base\Model $model the data model being validated
* @param string $attribute the attribute being validated
* @param string $message the error message
* @param array $params values for the placeholders in the error message
*/
public function addError($model, $attribute, $message, $params = [])
{
$params['attribute'] = $model->getAttributeLabel($attribute);
if (!isset($params['value'])) {
$value = $model->$attribute;
if (is_array($value)) {
$params['value'] = 'array()';
} elseif (is_object($value) && !method_exists($value, '__toString')) {
$params['value'] = '(object)';
} else {
$params['value'] = $value;
}
}
$model->addError($attribute, Yii::$app->getI18n()->format($message, $params, Yii::$app->language));
}
可能的选择:
1) 选择最重要的相关字段并为其添加错误。
2) 选择多个重要的相关字段并向它们添加相同的错误消息(您可以在传递之前将消息存储并传递到单独的变量中以保持代码干燥)。
3)您可以使用不存在的属性名称来添加错误,比如all,因为此时不检查属性是否存在。
class YourForm extends \yii\base\Model
{
/**
* @inheritdoc
*/
public function rules()
{
return [
['name', 'yourCustomValidationMethod'],
];
}
/**
* @return boolean
*/
public function yourCustomValidationMethod()
{
// Perform your custom validation here regardless of "name" attribute value and add error when needed
if (...) {
$this->addError('all', 'Your error message');
}
}
}
请注意,您仍然需要将验证器附加到现有属性(否则将引发异常)。使用最相关的属性。
因此,您只会在错误摘要中看到错误。您可以以如下形式显示错误摘要:
<?= $form->errorSummary($model) ?>
但在大多数情况下,总是有一个或多个属性与错误相关,因此我建议使用选项 1 或 2。选项 3 是一种 hack,但我认为仍然可以很好地解决您的问题。
【讨论】: