Setting default model value depending on a scenario

牧云@^-^@ 提交于 2020-01-13 09:51:10

问题


I can't sort out why setting default value doesn't work for me.

Here is my controller:

class QueryController extends ActiveController

{
    public $modelClass = 'app\models\Query';
    public $createScenario = 'restCreate';
    public $updateScenario = 'restUpdate';

I don't override the default createAction method.

Model:

 class Query extends ActiveRecord 
{public function rules()
{
    return [
        [['userId', 'name', 'created', 'isOneTime', 'isArchived', 'settings', 'engine'], 'required'],
        [['userId'], 'integer'],
        [['name', 'settings', 'schedule'], 'string'],
        [['created', 'lastUpdate'], 'safe'],
        [['isOneTime', 'isArchived', 'isApi', 'valid'], 'boolean'],
        [['state', 'engine'], 'string', 'max' => 160],
        [['isApi'], 'default', 'value'=> false],
        [['isApi'], 'default', 'value'=> true, 'on' => 'restCreate']
    ];
} 
public function scenarios()
    {
            $scenarios = parent::scenarios();
            $scenarios['restCreate'] = ['name', 'state', 'isApi', 'isOneTime', 'settings', 'schedule'];
            $scenarios['restUpdate'] = ['name', 'state', 'isOneTime', 'settings', 'schedule' ];
        return $scenarios;
    }

When I create a new entry via a Rest controller, it should set isApi = true by default, but it doesn't work in a such way. How can I assign a default model values depending on scenario?


回答1:


You should swap this rules:
[['isApi'], 'default', 'value'=> false]
[['isApi'], 'default', 'value'=> true, 'on' => 'restCreate']

You must do this because DefaultValueValidator appling only one time for single field. This validator run only if field's value is empty. There is this check: \yii\validators\DefaultValueValidator::validateAttribute()

Model runs validators one by one. [['isApi'], 'default', 'value'=> false] sets value for field to false. [['isApi'], 'default', 'value'=> true, 'on' => 'restCreate'] see that value is not empty and skipped.




回答2:


Yii uses only fields from current scenario. By default it sets in \yii\base\Model::SCENARIO_DEFAULT (default). Default scenario contains all fields from rules without on attribute.

If you want to use custom scenario, you must set it. You can do this by two ways:

  1. By constructor.
    $model = new Query(['scenario'=>'restCreate']);

  2. By setter.
    $model = new Query();
    $mosel->setScenario('restCreate');

See this link for more information about scenarios.

P.S. Good practice is using constants as scenario names. It help you make fewer mistakes in names of scenarios. For example:

class Query extends ActiveRecord {
    const SCENARIO_REST_CREATE = 'restCreate';
    const SCENARIO_REST_UPDATE = 'restUpdate';

    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios[static::SCENARIO_REST_CREATE ] = [/*...*/];
        $scenarios[static::SCENARIO_REST_UPDATE ] = [/*...*/];
        return $scenarios;
    }
}



回答3:


In your action :

public function ActionCreate(){
$model->scenario = 'restCreate';// it will set your scenario first .
 //remaining code for write here
}


来源:https://stackoverflow.com/questions/34345314/setting-default-model-value-depending-on-a-scenario

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!