简体   繁体   中英

How to create scenario in Yii2 with no validation rules active?

I have MyEntity.php model. As a part of the model script, there are some rules and some scenarios defined:

public function rules()
{
    return [
        [['myentity_id', 'myentity_title', 'myentity_content', 'myentity_date'], 'required'],
        [['myentity_id'], 'integer'],
        [['myentity_title', 'myentity_content'], 'string', 'max' => 120],
        [['myentity_date'], 'safe'],            
    ];
}

public function scenarios()
{
    $scenarios = parent::scenarios();
    $scenarios['scenario_one'] = ['myentity_id', 'myentity_title'];
    $scenarios['scenario_two'] = ['myentity_id', 'myentity_content'];
    return $scenarios;
}

I need to be able to have different scenarios, and for different actions only certain validations (by params) to be active. For example, scenario_one for actionOne, scenario_two for actionTwo etc.

Here is some small part of code from the controller:

public function actionOne($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_one';
    .
    .
    .
}

public function actionTwo($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_two';
    .
    .
    .
}

Now I want to have a scenario_three where there should NOT be any validations at all. I'll have additional checks in code that will prevent failing while storing in database. I'll just need to make sure that no validations are applied because it's preventing my form from submitting. If I don't apply any scenario, then the default scenario is applied (all listed validations will be active, which is totally opposite of the scenario I need).

To be able to do this, you need to do a few things (including the ones you almost did yourself):

  • In your controller, write $modelMyEntity->scenario = 'scenario_three';

  • In model, add an additional scenario array 'scenario_three' in scenarios() method:

Like this:

$scenarios['scenario_three'] = ['myentity_id', 'myentity_content'];
  • Finally, most changes will be required in rules() as you will need to add where to include or exclude specific scenarios.

Basically, in each rule you can now write except conditional and point which attributes will not comply to which scenario. So in your example, let's say, let's exclude all attributes for scenario_three :

[['myentity_id', 'myentity_title', 'myentity_content', 'myentity_date'], 'required', 'except' => 'scenario_three'],
[['myentity_id'], 'integer', 'except' => 'scenario_three'],
[['myentity_title', 'myentity_content'], 'string', 'max' => 120, 'except' => 'scenario_three'],
[['myentity_date'], 'safe'],

This is a little different solution to how to ignore rules but I find this more attractive because in future it would be easier to add/remove specific attributes for this scenario and will also be easier for other developers (if there are more than just you) to understand what you're trying to do.

But I think @iStranger's solution works too (much simpler).

If I correctly understood your question, you can assign scenario_three as current scenario: model will not find matched rules and will skip validation checks.

public function actionThree($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_three';
    .
    .
    .
}

UPD: However I strictly recommend to define explicitly all scenarios and corresponding active attributes (in scenario method) and remove $scenarios = parent::scenarios(); , because it can cause unnecessary effects. Parent implementation is mostly developed to backward compatibility with Yii1, that has no scenarios() methods. And it is assumed usually if you override scenarios() method, you should not merge your explicitly defined scenarios with parent implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM