Ну, если я вас правильно понял, у меня есть предложение, основанное на чем-то похожем, что я делаю:
У меня есть базовая "особенность" модели. Но эта функция может быть «текстовой» или «графической» и т. Д. Но все они имеют общий «идентификатор функции» и несколько других столбцов. Поэтому я выбрал подход EAV . У меня есть одна таблица «функций», а затем у меня есть таблица для каждого подтипа (текст, изображение и т. Д.). Один из столбцов в таблице «Feature» содержит информацию о подтипе. Затем в моем методе "afterFind ()" на базовой модели "Feature" я смотрю на столбец подтипа. Если подтипом является «текст», я присоединяю поведение «текстового» типа, которое я сделал. Это поведение получает переменные из таблицы подтипов и настраивает их для доступа так же, как атрибуты базовой модели.
Примерно так:
client_device_table : (базовая таблица)
-client_id (первичный ключ)
-service_id
-core_device_id
-device_type (имя поведения, например CableModemBehavior или VoipGatewayBehavior)
cable_modem_table
-core_device_id
-modem_info_1
-modem_into_2
voip_gateway_table
-core_device_id
-gateway_info_1
-gateway_into_2
В модели ClientDevice CActiveRecord (базовая модель):
protected function afterFind() {
parent::afterFind();
// remember $this->device_type holds the relevant behavior i.e. CableModemBehavior
$this->attachBehavior($this->device_type,call_user_func(array($this->device_type, 'model')));
}
И поведение выглядит примерно так:
class CableModemBehavior extends CActiveRecordBehavior {
public modem_info_1;
public modem_info_2;
public function attach($owner)
{
parent::attach($owner);
$connection = Yii::app()->getDb();
$command=$connection->createCommand("SELECT *
FROM cable_modem_table
WHERE core_device_id=:device_id");
$command->bindParam(':device_id',$this->owner->core_device_id);
$data=$command->queryRow();
$this->modem_info_1 = $data->modem_info_1;
$this->modem_info_2 = $data->modem_info_2;
}
}
Это не проверено, но СЛЕДУЕТ произойти сейчас, если вы получите модель ClientDevice с CableModemBehavior в качестве записи столбца подтипа , вы сможете получить доступ к атрибутам модема (modem_info_1) так же, как обычные атрибуты ClientDevice (client_id):
ClientDevice-> modem_info_1
Будет, конечно, нечто большее, чем это. Это только для случая "найти". Вам нужно будет проделать еще некоторую работу, чтобы заставить массовое назначение атрибутов работать для $ _POST, или передавать Relations, или добавить методы afterDelete, validate и afterSave для поддержки сохранения и удаления и т. Д., Но я надеюсь, что это полезно начать.
Вы также можете сделать это намного лучше, переопределив методы __get и __set базовой модели в поведении, так что если запрашивается столбец из таблицы подтипов, он идет и получает его из текстовой таблицы прозрачно, выполнение поиска схемы для получения имен столбцов и т. д. Лучше, чем жесткое кодирование, как я делал в этом примере. Было бы полезно взглянуть на EavBehavior в репозитории yiiext и AdvancedArBehavior (или аналогичных), чтобы понять, как сделать его более гладким. Вместо поведения для каждого подтипа, вы можете иметь общее поведение и просто передать имя таблицы подтипов. (ооо мне это нравится на самом деле)
Ура!