Как изменить формат атрибута в CActiveRecord, возвращаемом методом findAll?

У меня есть атрибут в моей модели, который хранится в двоичном формате в базе данных. В случае, если атрибут является геометрическим (многоугольным) объектом.

Этот объект может быть приведен к нескольким строковым представлениям. Итак, как я могу прикрепить событие после выполнения поиска, которое позволяет мне изменять атрибут только для возвращенного набора?

Моим первым предположением было использование события onAfterFind, но оно не вызывает обработчик с созданным элементом, как предполагает документация. Моей первой попыткой было следующее в контроллере.

// an activeRecord class
GeoTableBinaryData extends CActiveRecord {
 ... // normal active record with a table which has a binary attribute called geom
}

$model = GeoTableBinaryData::model();
$model->onAfterFind->add(
  function( CEvent $evt ){
    // get the finded object to update the geom attribute on the fly here want
    // a text representation in other case would transform it to XML or JSON
  }
);

foreach ( $model->findAll() as $geoInfo )
{
  ... // output serialized geometry
}

2 ответа

Решение

Вы также можете написать геттеры для разных форматов:

public function getGeoAsString()
{
    // Create the string from your DB value. For example:
    return implode(',', json_decode($this->geom));
}

Тогда вы можете использовать geoAsString как обычный (только для чтения) атрибут. Вы также можете добавить метод установки, если хотите сделать его доступным для записи.

Правильный способ сделать это состоит в том, что в вашей модели есть метод afterFind, такой как:

protected function afterFind()
{
     $this->someAttribute = $this->methodToChangeTheAttribute($this->someAttribute);
     return parent::afterFind();
}

и все, когда вы будете использовать методы AR, каждая найденная модель будет проходить через afterFind() и изменить someAttribute как ты хочешь.

Другие вопросы по тегам