【问题标题】:Yii2: Validation rules for whole model object instead of single attributes?Yii2:整个模型对象而不是单个属性的验证规则?
【发布时间】:2015-05-21 08:35:28
【问题描述】:

考虑一下我有这样的东西:

class Dummy extends yii\base\Model {
    public $a;
    public $b;

    public function rules() {
         return [ ??? ];
    }
}

如何同时考虑属性 $a 和 $b 创建验证规则?想象一下 $a 或 $b 或两者都应该有一个值。如果没有设置它们,我希望得到一个验证错误,例如“必须设置 a 或 b”。我认为 when property 在这里没有帮助(我可以为每个属性创建 when 条件,分别检查另一个属性,但这会产生两个验证错误)。

上面的例子很简单。但它可能要复杂得多,并且还依赖于其他事物。

由于Model::addError() 需要一个属性,我似乎无法实现这一点。错误取决于属性。那么我还能如何验证整个对象,例如找出模型对象是否可以与其当前值一起保存。在属性验证之上是否有任何类型的验证?更高级别的验证?

【问题讨论】:

    标签: php validation yii2


    【解决方案1】:

    我相信您需要的是自定义验证规则:

    public function rules()
    {
        return [
            [['a', 'b', 'c'], 'myCustomRule'],
        ];
    }
    
    public function myCustomRule($attribute)
    {
        if(!$this->a && !$this->b && !$this->c) {
            $this->addError($attribute, "One of these attributes is required: a, b, c");
        }
    }
    

    【讨论】:

    • 谢谢,但这不是我所期望的。这会导致 3 个错误,因为该规则是按属性执行的。
    • 是的,我是故意这样做的:用户将看到三个突出显示的字段,并且会知道我们在错误消息中的意思是什么字段。如果你愿意,你可以只留下一个,仍然会检查所有三个:``` public function rules() { return [ [['a',], 'myCustomRule'], [['b', 'c'] , 'string'], // 或者其他的 ]; }```
    【解决方案2】:

    根据guide 可以将* 作为属性传递给addError($attribute, $error)。但是,由于消息未绑定到现有属性,因此消息需要以 errorSummary() 作为 ActiveForm 的一部分显示。

    模型中的规则

    public function rules() {
        return [
            [['a', 'b'], 'validateAandB'],
        ];
    }
    

    验证方法:

    public function validateAandB($attribute, $params) {
        $this->addError('*', 'a and/or b should have a value.');
    }
    

    以形式看:

    <?php $form = ActiveForm::begin(); ?>
        <?= $form->errorSummary($model) ?>
        <?= $form->field($model, 'a') ?>
        <?= $form->field($model, '') ?>
        <?= Html::submitButton('Submit', ['class' => 'btn btn-success']) ?>
    <?php ActiveForm::end(); ?>
    

    其实不用*,任何字符串都可以。如果是属性名称,则会在输入附近和摘要中显示验证错误,否则仅在摘要中显示(摘要不显示属性名称,仅显示错误消息)。

    注意,由于对两个属性进行了验证,因此消息被添加了两次。但是,由于它是为同名添加的(此处为:*),并且默认情况下仅显示属性的第一条消息,因此只会显示一次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-05
      • 2019-07-06
      • 2012-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多