Search code examples
validationyii2scenariosvalidationrulesyii-validation

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).


Solution

  • 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).