Переопределяем __set и __get методы для аттрибута модели Yii2

Не всегда получается красиво сохранить приходящие данные в БД, к примеру такая ситуация может возникнуть при сохранении списка в одну ячейку, чтобы было более понятно приведу часть кода представления:

$form->field($model, 'color')->checkboxList(Yii::$app->params['color'], [
   'item' => function($index,$label,$name, $checked, $value){
      return Html::checkbox($name, $checked, [
         'value' => $value,
         'label' => '<label class="color ' . $label .'" for="' . $value . '"></label>',
         'id' => $value
      ]);
   }
]);

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

а в контроллере у нас уже написано стандартное

if ($model->load(Yii::$app->request->post()) && $model->save()) {
   ...
}

и не хотелось бы убирать красивый и понятный метод загрузки и сохранения модели, притом в БД нам нужно просто сохранить, а потом получить значения (без возможности дальнейшей выборки для фильтрации), в этом случае можно переопределить магические методы __set и __get в нашей модели:

public function __set($name, $value) {
   if ($name === 'color') {
      $this->setAttribute('color', serialize($value));
   } else {
      parent::__set($name, $value);
   }
}

public function __get($name) {
   if ($name === 'color') {
      return unserialize($this->getAttribute('color'));
   }
   return parent::__get($name);
}

в итоге у нас получится что при сохранении мы присваиваем нашему аттрибуту color сериализованный массив, а при выводе мы преобразовываем сериализованную строку в массив.

не забываем в правилах сделать аттрибут color безопасным

['color', 'safe']
comments powered by HyperComments
Valentin Tsibin
2015-05-30 14:12:05
Чтобы было совсем изящно, если используется постгрес, можно сохранить пользовательский ввод в поле типа json. Для остальных СУБД, как вариант, в виде битовой маски.
Алексей
2015-06-01 20:14:27
полностью согласен, основной посыл в том как можно обработать данные перед сохранением с помощью set и get
mr. Mirocow
2015-11-03 02:31:34
это решение не очень красивое лучше использовать <code> public function getColor(){ // } </code> и <code> public function setColor(){ // } </code>
Александр Семёнов
2016-07-31 20:20:35
А как поступать при условии что необходимо сериалайзить несколько полей в БД?
При копировании материалов обратная ссылка на play-stop.ru желательна обязательна!