问题
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:
By constructor.
$model = new Query(['scenario'=>'restCreate']);
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