Как создать сценарий в Yii2 без активных правил проверки?
У меня есть модель MyEntity.php. В рамках скрипта модели определены некоторые правила и некоторые сценарии:
public function rules()
{
return [
[['myentity_id', 'myentity_title', 'myentity_content', 'myentity_date'], 'required'],
[['myentity_id'], 'integer'],
[['myentity_title', 'myentity_content'], 'string', 'max' => 120],
[['myentity_date'], 'safe'],
];
}
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['scenario_one'] = ['myentity_id', 'myentity_title'];
$scenarios['scenario_two'] = ['myentity_id', 'myentity_content'];
return $scenarios;
}
Мне нужно иметь возможность иметь разные сценарии, и для разных действий должны быть активны только определенные проверки (по параметрам). Например, scene_one для actionOne, scene_two для actionTwo и т. Д.
Вот небольшая часть кода из контроллера:
public function actionOne($id)
{
$modelMyEntity = $this->findModel($id);
$modelMyEntity->scenario = 'scenario_one';
.
.
.
}
public function actionTwo($id)
{
$modelMyEntity = $this->findModel($id);
$modelMyEntity->scenario = 'scenario_two';
.
.
.
}
Теперь я хочу иметь сценарий_три, где вообще не должно быть никаких проверок. У меня будут дополнительные проверки в коде, которые предотвратят сбой при сохранении в базе данных. Мне просто нужно убедиться, что никакие проверки не применяются, потому что это препятствует отправке моей формы. Если я не применяю какой-либо сценарий, то применяется сценарий по умолчанию (все перечисленные проверки будут активными, что полностью противоположно сценарию, который мне нужен).
2 ответа
Чтобы сделать это, вам нужно сделать несколько вещей (включая те, которые вы почти сделали сами):
В вашем контроллере напишите
$modelMyEntity->scenario = 'scenario_three';
В модели добавьте дополнительный массив сценариев
scenarios()
метод:
Как это:
$scenarios['scenario_three'] = ['myentity_id', 'myentity_content'];
- Наконец, большинство изменений потребуются в
rules()
так как вам нужно будет добавить, куда включить или исключить конкретные сценарии.
В принципе, в каждом правиле вы можете написать except
условно и укажите, какие атрибуты не будут соответствовать какому сценарию. Итак, в вашем примере, скажем, давайте исключим все атрибуты для scenario_three
:
[['myentity_id', 'myentity_title', 'myentity_content', 'myentity_date'], 'required', 'except' => 'scenario_three'],
[['myentity_id'], 'integer', 'except' => 'scenario_three'],
[['myentity_title', 'myentity_content'], 'string', 'max' => 120, 'except' => 'scenario_three'],
[['myentity_date'], 'safe'],
Это немного другое решение для того, чтобы игнорировать правила, но я считаю это более привлекательным, потому что в будущем будет проще добавлять / удалять определенные атрибуты для этого сценария, а также будет проще для других разработчиков (если их будет больше, чем только вас) чтобы понять, что вы пытаетесь сделать.
Но я думаю, что решение @ iStranger тоже работает (намного проще).
Если я правильно понял ваш вопрос, вы можете назначить scenario_three
как текущий сценарий: модель не найдет подходящих правил и пропустит проверки проверки.
public function actionThree($id)
{
$modelMyEntity = $this->findModel($id);
$modelMyEntity->scenario = 'scenario_three';
.
.
.
}
UPD: Однако я настоятельно рекомендую четко определить все сценарии и соответствующие активные атрибуты (в scenario
метод) и удалить $scenarios = parent::scenarios();
, потому что это может вызвать ненужные эффекты. Родительская реализация в основном разработана для обратной совместимости с Yii1, которая не имеет scenarios()
методы. И это обычно предполагается, если вы переопределите scenarios()
метод, вы не должны объединять ваши явно определенные сценарии с родительской реализацией.