И смех и грех

Динамическая модель в Yii2

Динамическая модель Yii2Привет друзья. Сегодня у меня небольшая статья и, как вы уже догадались речь пойдет о динамической модели в Yii2.

Кратко напомню ,что такое динамическая модель.

Динамическая модель (DynamicModel) — это модель класса, в основном используемый для поддержки специальной проверки данных. Если сказать просто, то это модель, которая предназначена для специфической валидации.

Как мы знаем, обычно модели, если мы говорим об обычных моделях создают некую жесткую структуру для валидации данных. Что я имею ввиду? Что описываем изначально структуру модели, которая предназначена для работы, например с таблицей в БД. А в модели, мы описываем те поля, которые там есть в таблице, а так же правила для их валидации. Например приведу пример модели LoginForm

public $username;
public $password;
public $rememberMe = true;
private $_user = false;

public function rules()
{
	return [
		// username and password are both required
		[['username', 'password'], 'required'],
		// rememberMe must be a boolean value
		['rememberMe', 'boolean'],
		// password is validated by validatePassword()
		['password', 'validatePassword'],
	];
}
public function attributeLabels()
{
	return [
	   'username'=>'Пользователь',
	   'password'=>'Пароль'
	];
}

Если посмотреть, то мы описали 4 свойства и 2 метода для проверки и для вывода атрибутов.

Но как быть в ситуации, когда мы не знаем сколько у нас будет свойств, такое может произойти когда например мы создаем супер форму с неограниченным количеством полей.

И тогда на помощь к нам приходят динамические модели, которые справятся с этой нашей задачей и немного разгрузят наш мозг, придумывая и ограничивая форму.

Приведу небольшой пример динамической модели:

public function getModel($form_elements)  //Принимаем на вход список элементов
{
	$model = new DynamicsModel();  //Создаем новый экземпляр динамической модели
	if(is_array($form_elements))  //Проверяем, является ли пришедший к нам объект массивом 
	{
		foreach($form_elements as $key => $form_element){
			$nameEl = !empty($form_element->name) ? $form_element->name : 'Не указано_'.$key;
			$name = Translite::strTranslite($nameEl);  // Метод транслитерации из русских слов в латинские, они и будут у нас динамическими свойствами
			$_labelDynamic[$name] = $form_element->name;
			$model->defineAttribute($name);

			//Установки типа правила для Динамической валидации
			switch ($form_element->type)
			{
				case 1:
					$model->addRule($name, 'integer');
					break;
				case 2:
					$model->addRule($name, 'string', ['min' => 1, 'max' => 255]);
					break;
				default:
					$model->addRule($name, 'safe');
					break;
			}
		}
		$model->validate();
		$model->setAttributeLabels($_labelDynamic);  // Устанавливаем массив атрибутов для модели из подготовленного массива
	}
	return $model;
}

В общем и целом получается как то так. Если есть какие то вопросы или замечания буду рад с вами их обсудить.

Спасибо

3 комментария

  • Дмитрий

    Здравствуйте!
    Как можно сохранить данные такой динамической модели в БД? Ведь полей полученных из динамической модели может не быть (точно не быть) в базе данных.

    • Дмитрий

      Добрый день.
      Для динамической модели я создавал предварительно метод-конструктор который собирает форму.
      Поля в будущей форме, я уже предварительно предполагал какие в ней будут, соответственно их мы формируем.
      Наименование поля, тип поля, описание поля и сохраняю эти данные бд.
      Общая суть такая, что есть некий конструктор который я задаю в формате:
      Наименование поля ; Тип поля (string, integer, boolean) ; Описание поля.
      И таких полей может быть много, это что то вроде заготовки будущей формы, которую я потом формирую через метод сбора этих данных и вывожу уже в готовом виде.


      private function _createModel(array $form_elements): DynamicsModel
      {
      $_labelDynamic = [];
      $model = new DynamicsModel();
      foreach($form_elements as $key => $form_element){
      $nameEl = !empty($form_element->name) ? $form_element->name : 'Не указано_'.$key;
      $name = Translite::strTranslite($nameEl);
      $_labelDynamic[$name] = $form_element->name;
      $model->defineAttribute($name);

      //Установки типа правила для Динамической валидации
      switch ($dds_form_element->type)
      {
      case 1:
      $model->addRule($name, 'integer');
      break;
      case 2:
      $model->addRule($name, 'string', ['min' => 1, 'max' => 255]);
      break;
      default:
      $model->addRule($name, 'safe');
      break;
      }
      }
      $model->validate();
      $model->setAttributeLabels($_labelDynamic);
      return $model;
      }

      Надеюсь объяснил понятно, если нужны пояснения я дополню статью или прокомментирую.

Добавить комментарий

Войти с через: 

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Защита от роБота * Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.