Как изменить формат атрибута в 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
}

person cavila    schedule 28.05.2013    source источник


Ответы (2)


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

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

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

person Michael Härtl    schedule 29.05.2013

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

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

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

person Twisted1919    schedule 28.05.2013
comment
Но если это единственный способ, то в чем смысл событий ( ​​onAfterFind ) в Yii, если вы не можете их слушать и реагировать? Я попытался прикрепить список к afterFind, чтобы сделать это, но eventListener никогда не был уведомлен о том, что AR создал новые экземпляры. Ошибка ? - person cavila; 29.05.2013
comment
Вы можете создать поведение для присоединения к методу afterFind(). Кроме того, вы должны изучить, как правильно прикрепить обработчик событий, просто взгляните на CActiveRecordBehavior, чтобы узнать, как это делается, или прочитайте документацию. - person Twisted1919; 29.05.2013