7

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?

Insane Skull
  • 9,220
  • 9
  • 44
  • 63

3 Answers3

1

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;
    }
}
Haru Atari
  • 1,502
  • 2
  • 17
  • 30
  • 1
    thank you for your examples, I've read this part of documenation before posting here. Since my controller `extends ActiveController` there are predefined public properties `$createScenario` and `$updateScenario` which allows to set scenario in my controller bu this code `public $createScenario = 'restCreate'; public $updateScenario = 'restUpdate'; ` http://www.yiiframework.com/doc-2.0/yii-rest-activecontroller.html#$createScenario-detail – Ivan Nosyrev Dec 18 '15 at 18:17
  • @IvanNosyrev Май инглиш из вери бэд. Я не совсем понял, у вас вопрос какой-то остался? Или вы просто объяснили, почему не используете константы? – Haru Atari Dec 18 '15 at 18:59
  • вопрос остался тот же что и в сабже. Вопрос не про константы, и не про то как засеттить сценарий. Вопрос в том, что поле не принимает дефолт значение из rules. – Ivan Nosyrev Dec 18 '15 at 19:11
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.

Haru Atari
  • 1,502
  • 2
  • 17
  • 30
0

In your action :

public function ActionCreate(){
$model->scenario = 'restCreate';// it will set your scenario first .
 //remaining code for write here
}
Amitesh Kumar
  • 3,051
  • 1
  • 26
  • 42
  • 1
    It is not necessary to do it in a such way. Setting public properties `public $createScenario = 'restCreate'; public $updateScenario = 'restUpdate';` should be enough. – Ivan Nosyrev Dec 18 '15 at 18:28
  • then it will applied on all action and you can't default value accurate. – Amitesh Kumar Dec 18 '15 at 19:04