我想为ActiveRecord应用验证器但不适用于特定字段,我的意思是,我希望在表单的错误摘要中看到验证器但不与特定字段关联。
答案 0 :(得分:0)
编写自定义验证时,您需要使用addError
yii\base\Model
方法(如果您在模型中编写)或yii\validators\Validator
(如果您编写单独的验证程序)。
两种方法都需要传递$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)选择多个重要的相关字段并向其添加相同的错误消息(您可以在传递以保留代码DRY之前在单独的变量中存储和传递消息)。
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 是一种破解,但我认为仍然是非常优雅的解决方案。