Как создать сценарий в 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;
}

Мне нужно иметь возможность иметь разные сценарии, и для разных действий должны быть активны только определенные проверки (по параметрам). Например, сценарий_один для действияОдин, сценарий_два для действияДва и т. д.

Вот небольшая часть кода из контроллера:

public function actionOne($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_one';
    .
    .
    .
}

public function actionTwo($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_two';
    .
    .
    .
}

Теперь я хочу иметь сценарий_3, в котором вообще НЕ должно быть никаких проверок. У меня будут дополнительные проверки в коде, которые предотвратят сбой при сохранении в базе данных. Мне просто нужно убедиться, что никакие проверки не применяются, потому что это препятствует отправке моей формы. Если я не применяю какой-либо сценарий, то применяется сценарий по умолчанию (все перечисленные проверки будут активны, что полностью противоположно тому сценарию, который мне нужен).


person delux    schedule 25.09.2016    source источник


Ответы (2)


Чтобы иметь возможность сделать это, вам нужно сделать несколько вещей (включая те, которые вы почти сделали сами):

  • В вашем контроллере напишите $modelMyEntity->scenario = 'scenario_three';

  • В модели добавьте дополнительный массив сценариев '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 тоже работает (намного проще).

person Gytis TG    schedule 25.09.2016
comment
Мне нравится использование кроме условного - person Kiran Muralee; 25.09.2016
comment
@KiranMuralee Спасибо за поддержку! Я надеюсь, что другие найдут это полезным. - person Gytis TG; 25.09.2016
comment
Это решение немного лучше, потому что в таком случае jQuery все равно будет показывать проверку (правда, зеленые поля), если вы сделаете еще несколько изменений с помощью jQuery. - person ; 25.09.2016
comment
@Edvin Tenovimas Эта информация находится в руководстве по Yii2. Я искал ее, но не смог найти. Однако я обнаружил использование «on». Например, // имя пользователя, адрес электронной почты и пароль требуются в сценарии регистрации [['username', 'email ', 'пароль'], 'обязательно', 'вкл' =› self::SCENARIO_REGISTER], - person Kiran Muralee; 25.09.2016
comment
@KiranMuralee Я могу предоставить очень подробную информацию об этих сценариях, если хотите. Но лучше использовать либо электронную почту, либо что-то подобное, потому что объяснение займет больше места, чем комментарии позволяют символы. :) Короче, я считаю, что должен быть хотя бы один пример с except, но не уверен, не проверял. - person Gytis TG; 25.09.2016
comment
@EdvinTenovimas Хорошо. Позвольте мне попробовать это на практике. Если это работает, это действительно полезно, спасибо за информацию :) - person Kiran Muralee; 25.09.2016
comment
@KiranMuralee Если вам нужна дополнительная помощь, вы можете написать либо создать новый вопрос, либо написать мне по электронной почте. :) Я должен заметить в обоих случаях. - person Gytis TG; 25.09.2016
comment
except — типичная функция Yii1. Конечно, это сработает. Однако, на мой взгляд, это не удобно, когда у вас больше 5 сценариев и 20 атрибутов. В этом случае метод rules будет нечитаемым. Yii2 позволяет разделить управление активными/безопасными атрибутами (методом scenarios) и правилами проверки (методом rules). Я думаю, это вызывает меньше путаницы в коде. - person IStranger; 25.09.2016
comment
@IStranger Ну, это зависит от того, к чему привыкли программисты. Лично я предпочитаю описывать все сценарии в модели, независимо от того, сколько атрибутов используется. - person Gytis TG; 25.09.2016
comment
@EdvinTenovimas Конечно, именно поэтому Yii2 оставили реализацией Yii1: часть программистов считают такой подход более удобным :) - person IStranger; 25.09.2016
comment
@IStranger Ну, я никогда не использовал Yii1, просто я видел, что предпочитаю этот способ, так как для меня это немного проще. Я вижу, мы могли бы много говорить о Yii2. Я должен помнить об этом на случай, если мне понадобится помощь в будущем. - person Gytis TG; 25.09.2016
comment
@EdvinTenovimas Меня смущает тот факт, что в правилах, которые вы определяете для атрибутов, они не должны быть включены в сценарий, кроме слова. С другой стороны, при определении сценария в методе сценариев вы указываете там два атрибута. Так нужно ли нам перечислять их там? Должен ли сценарий быть определен там (в методе сценариев) вообще? - person delux; 02.10.2016
comment
@delux Если вы исключаете эти атрибуты из сценария scenario_three (и из rules()), входные значения с такими атрибутами будут игнорироваться системой (ввод пользователя не будет иметь значения). В вашем случае вы можете удалить атрибуты из scenario_three, но тогда они будут иметь все правила, которые применяются к другим сценариям (если они есть), или вы можете получить что-то вроде сценария undefined (Сегодня вечер, поэтому трудно думать и объясните, я могу сделать это завтра). :) - person Gytis TG; 02.10.2016
comment
@EdvinTenovimas, пожалуйста, найдите время и обдумайте мой вопрос из комментария (когда сможете). Меня все еще смущает факт из моего последнего комментария. - person delux; 06.10.2016
comment
@delux Проще говоря, в вашем случае решение IStranger тоже может сработать. Только мой случай работает, когда вы собираетесь добавить больше атрибутов (вы хотите проверить) в будущем. - person Gytis TG; 06.10.2016

Если я правильно понял ваш вопрос, вы можете назначить scenario_three текущим сценарием: модель не найдет совпадающие правила и пропустит проверки проверки.

public function actionThree($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_three';
    .
    .
    .
}

UPD: Однако я настоятельно рекомендую явно определить все сценарии и соответствующие активные атрибуты (в методе scenario) и удалить $scenarios = parent::scenarios();, поскольку это может привести к ненужным эффектам. Родительская реализация в основном разработана для обратной совместимости с Yii1, который не имеет scenarios() методов. И обычно предполагается, что если вы переопределяете метод scenarios(), вам не следует объединять явно определенные сценарии с родительской реализацией.

person IStranger    schedule 25.09.2016
comment
Мне он тоже нравится, он довольно простой и понятный. :) Вот вам голосование. - person Gytis TG; 25.09.2016
comment
@EdvinTenovimas Спасибо) - person IStranger; 25.09.2016
comment
@IStranger, не могли бы вы также опубликовать фрагмент кода, как это описание должно выглядеть на практике (какие изменения следует применить в функциях rules () и scripts () из моего исходного вопроса)? - person delux; 07.10.2016