Solução definitiva para Scenarios

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.