问题
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