1

In model I have defined multiple scenarios:

public function rules() {
    return [
        [['in_quantity'], 'required','on'=>['stockIn']],
        [['out_quantity'], 'required','on'=>['stockOut']],
    ];
}

Is it possible to use both scenario stockIn and stockOut for single model validation?

$StockModel->scenario[] = 'stockOut';
$StockModel->scenario[] = 'stockIn';

or

 $StockModel->scenario = ['stockOut','stockIn'];

3 Answers3

3

You can't have multiple scenarios for model. But you can have multiple scenarios for rule:

public function rules() {
    return [
        [['in_quantity'], 'required', 'on' => ['stockIn', 'stockOut']],
        [['out_quantity'], 'required', 'on' => ['stockIn', 'stockOut']],
    ];
}

If you need multiple scenarios for model, it means that you're overusing scenarios feature.

Also note that it is not recommended to use too many scenarios in one model - scenarios work fine for simple cases, but more complicated cases should be handled by separate models for each scenario.

rob006
  • 21,383
  • 5
  • 53
  • 74
  • That is the point - you can't have multiple scenarios at the same time in model. Even if you adjust model to allow multiple scenarios, it is just bad pattern (model no longer controls validation). – rob006 Nov 26 '19 at 12:00
1

You can create multiple scenarios this way in model

class MyModel extends \yii\db\ActiveRecord {
const SCENARIO_CREATE = 'scenario_create';
const SCENARIO_UPDATE = 'scenario_update';


// get scenarios
public function scenarios()
{
     return [
      self::SCENARIO_CREATE      =>  ['user_id', 'name', 'desc', 'published','date_create'],
      self::SCENARIO_UPDATE      =>  ['user_id', 'name', 'desc', 'date_update'],
  ];
}


  public function rules()
  {
          [['user_id'], 'integer'],
          [['name','desc'], 'string', 'max' => 70],
          [['date_create', 'date_update'], 'date', 'format' => 'php:Y-m-d H:i:s'],
      ];
  }
}

and you can use this way anywhere

public function actionIndex() {
   $model = new MyModel;
   $model->scenario = MyModel::SCENARIO_CREATE;

   if ($model->load(\Yii::$app->request->post())){

      if($model->save()){
        // some operations
      } 
   }
}
0

You could if you extend the rule with when for server validation:

 [
   ['in_quantity'], 
   'required', 
   'when' => function ($model) {
                    return $model->scenario === 'stockIn' || $model->scenario === 'stockOut';
             }
  ]

Also if you want to validate in the form (aka client side validation) you could also use the whenClient that expect a js function:

'whenClient' => "function (attribute, value) {
                    const scenario = $('#stock-scenario').val()
                    return scenario === 'stockIn' || scenario = 'stockOut';
                }"
Josep Vidal
  • 2,580
  • 2
  • 16
  • 27
  • but i want to initilize multiple scenarios in single model to validate. this is working only for single scenarios initilization at a time – Shringiraj Dewangan Nov 26 '19 at 11:52
  • @ShringirajDewangan A model can only have 1 scenario at a time. You are missusing scenarios, they are not designed for that, you need to create a new model. – Josep Vidal Nov 26 '19 at 11:55