Yii2 - 动态切换模型中设置的规则

Yii2 - dynamically switch rules set in model

我想根据表单上的开关值动态替换模型中的规则。

在视图中:

<?php
    $form = ActiveForm::begin([
        'enableAjaxValidation' => true,
        'validationUrl' => Url::toRoute('anounce/validation')
    ]);
?>

在控制器中:

public function actionValidation()
{
    $model = new Anounce();
    if (Yii::$app->request->isAjax && $model->load(Yii::$app->
        request->post())) {
        Yii::$app->response->format = 'json';
        return ActiveForm::validate($model);
    }
}

模型摘录:

class Anounce extends \yii\db\ActiveRecord
{
    private $currentRuleSet;    // Current validation set
    // Here are arrays of rules with assignment
    private $fullRuleSet;  // = [...];
    private $shortRuleSet; // = [...];
    private $minRuleSet;   // = [...];

    public function init()
    {
        parent::init();
        $this->currentRuleSet = $this->fullRuleSet;
    }

    public function rules()
    {
        return $this->currentRuleSet;
    }

    public function beforeValidate()
    {
        if ($this->idanounce_type === self::FULL) {
            $this->currentRuleSet = $this->fullRuleSet;
        } else if ($this->idanounce_type === self::SHORTER) {
            $this->currentRuleSet = $this->shortRuleSet;
        } else if ($this->idanounce_type === self::MINIMAL) {
            $this->currentRuleSet = $this->minRuleSet;
        }
        return parent::beforeValidate();
    }
}

变量idanounce_type是规则之间的切换。 不幸的是,验证是根据完整的规则集(或 init 中使用的规则集)进行的,尽管 *RuleSet 值已分配给 currentRuleSet

如何写规则的动态切换?

您在这里想要的是根据用户的输入更改验证。您可以通过在模型中定义场景来做到这一点。

因此,首先设置场景,将要验证的字段放入其中。例如,如果您有 usernamepasswordemail 字段,并且您定义了两个场景,在 SCENARIO_FIRST 中只有 usernamepassword 会得到验证。

public function scenarios()
{
    return [
        self::SCENARIO_FIRST => ['username', 'password'],
        self::SCENARIO_SECOND => ['username', 'email', 'password'],
    ];
}

然后在你的控制器中,根据输入设置场景:

public function actionValidation()
{
    $model = new Anounce();

    //example
    if($condition == true) 
    {
       $model->scenario = Anounce::SCENARIO_FIRST;
    }

    if (Yii::$app->request->isAjax && $model->load(Yii::$app->
        request->post())) {
        Yii::$app->response->format = 'json';
        return ActiveForm::validate($model);
    }
}

在此处详细了解场景以及如何在此处进行验证:

http://www.yiiframework.com/doc-2.0/guide-structure-models.html#scenarios