Boa noite pessoal,
Tive grandes dificuldades para lidar com scenarios, principalmente, quando precisamos editar alguma coluna ou criar uma nova instrução e modificamos no ruler e esquecemos do scenario, ou aplicamos no controller para save e esquecemos de modificar o ruler ou o scenario, então trouxe uma solução que para mim funciona bem, e torna a construção de saves e updates mais rápida e menos complicada. vamos lá.
Em meu model defino dois métodos importantes para lidar com o scenarios:
[list=1]
[*]getCustomScenarios = cria os scenarios
[*]RemoveOfRequired = remove da lista de scenarios as colunas que não desejo no required (evita aquele conflito de definir no scenario e esquecer no ruler)
[/list]
Estes dois métodos trabalharão para rules e controllers, fazendo assim que só por eles precisarei mexer para modificar ou aplicar novas regras, filtrando assim em 2 únicos pontos a edição e modificação de scenarios, evitando copias desnecessárias de colunas no controllers como $this->titulo = "…" ou save(true, […]), que na hora de editar você pode esquecer de um ou de outro e gerar uma dor de cabeça na hora de salvar no banco.
Vamos ao Model:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class Mymodel extends Model
{
const SCENARIO_CREATE = 'criar';
const SCENARIO_EDIT = 'editar';
//manipulo o scenarios
public function getCustomScenarios()
{
return [
self::SCENARIO_CREATE => ['title','description','state','date_creation'],
self::SCENARIO_EDIT => ['title','description','state','date_update'],
];
}
// para aplicar na rules
// in my code I do not want that SCENARIO_EDIT is required
public function RemoveOfRequired()
{
$allscenarios = $this->getCustomScenarios();
$allscenarios[self::SCENARIO_EDIT] = array_diff($allscenarios[self::SCENARIO_EDIT], ['date_update']);
return $allscenarios;
}
//aplico scenarios
public function scenarios()
{
//$scenarios = parent::scenarios();
$scenarios = $this->getCustomScenarios();
return $scenarios;
}
//minha rules obrigada a trabalhar com o scenario através de removeofRequired
public function rules()
{
$allscenarios = $this->RemoveOfRequired();
return [
[$allscenarios[self::SCENARIO_CREATE], 'required', 'on' => self::SCENARIO_CREATE],
[$allscenarios[self::SCENARIO_EDIT], 'required', 'on' => self::SCENARIO_EDIT],
///.... minhas outras regras
];
}
}
O Pulo do cato está no controller, perceba que em nenhum momento chamo colunas, ou salvo abruptamente confiando no model inteiramente. uso os métodos criados para trazer as colunas que desejo salvar baseado no scenario.
<?php
namespace app\controllers;
use app\models;
use Yii;
/**
*
*/
class Controller extends Controller
{
//para criacao
public function actionIndex()
{
$model = new Mymodel(['scenario'=>Mymodel::SCENARIO_CREATE]);
if ($model->load(Yii::$app->request->post())){
$modelScenarios = $model->getCustomScenarios();
// salvo desta maneira acho mais seguro.
if($model->save(true, $modelScenarios[$model->scenario])){
// return true
}
}
return $this->render('index');
}
// para edição
public function actionEdit($id)
{
$model = new Mymodel::findOne($id);
$model->scenario = Mymodel::SCENARIO_EDIT
if ($model->load(Yii::$app->request->post())){
$modelScenarios = $model->getCustomScenarios();
// salvo desta maneira acho mais seguro.
if($model->save(true, $modelScenarios[$model->scenario])){
// retorno verdadeiro
}
}
return $this->render('index');
}
}
Pessoal se alguém tiver uma ideia melhor, publica ai, para chegar neste resultado tive que lidar com muitos conflitos do tipo salvar pelo controller, e todos os registros dos posts não serem registrados por conta dos scenarios e dos rulers mal aplicados.