2010-08-25 39 views
0

我有幾個數據庫表,女巫是從一個表使用繼承構建女巫是創建新表的一種「模板」,現在我有一套商業邏輯方法適用於從模板繼承的列,其他列僅用作模型表示的參數,它們對邏輯沒有意義。Yii框架「元數據模型」創建+ postgres繼承

目標是在所有表格上共享商業邏輯方法,我知道現在可以通過添加另一個類來擴展CActiveRecord,並從它擴展到每個模型,或者將邏輯打包爲一個行爲並將其附加到其中到模型。 但是這需要爲每個表/模型至少寫入「轉儲」類文件,但這些表在系統中「存活」,並且將在系統生命週期中被刪除/創建。

有沒有辦法編寫某種「元模型」女巫將作爲參數,表名或可能某種方式來創建表模型「即時」並追加到它的業務邏輯?

我問過關於Yii的用戶板這一問題,但沒有發現任何的迴應:/ 我考慮這是某種形式的代碼的挑戰,所以任何幫助/線索,歡迎:)

[編輯]

一些樣品:針對不同的客戶端設備 表

  • hfc.cable_modem
  • lan.switch_port
  • lan.voip_gateway
  • (在不久的將來,會有更多的「技術」添加到系統中,所以新表的客戶端設備,並沒有放棄對他們中的一些支持的可能性)

每個表從模板表client_device女巫繼承有一個字段:

  • CLIENT_ID
  • service_id爲
  • core_dev ice_id
  • (加上像創建,更新,更新等timestampable行爲一些元列)

喜歡你所看到的商業邏輯只對ID的操作,並且其爲每個表相同,列的其餘部分被用作設備參數存儲/演示信息。

我的目標是擁有「元模型」客戶端設備,女巫將業務邏輯應用於所有這些表,並且仍然爲每個表提供對每個表的訪問特定字段的訪問權限,而無需編寫模型類(女巫我必須做的,每一次,當新技術將被添加,或支持給定的技術將在未來下降)

+0

使用Behaviors將模型動作動態附加到單個泛型模型類(並覆蓋它的表名)中可能有一種很流行的方法,但是沒有您正在嘗試做的更多具體示例(即代碼)我無法確定。謹慎解釋一下更詳細的信息?謝謝 – thaddeusmt 2010-08-25 22:29:27

+0

更多信息:) – canni 2010-08-26 08:22:29

回答

2

好吧,如果我明白你的權利,我有一個建議,基於類似的東西我在做:

我有一個基地「功能」模型。但該功能可以是「文本」功能或「圖像」功能等,但它們都共享「功能ID」和其他一些列。所以我採取了一種EAV方法。我有一個「功能」表,然後我有一個表,每個子類型(文本,圖像等)。「功能」表中的一列包含子類型信息。然後在基礎「特徵」模型的「afterFind()」方法中,我查看子類型列。如果子類型是「文本」,我附加了我所做的「文本」類型的行爲。此行爲從子類型表中獲取變量,並將它們設置爲與基本模型的屬性一樣被訪問。

像這樣:

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

有將是更多的比這一點,當然。這只是爲了「發現」的情況。你需要做更多的工作才能讓$ _POSTs的mass屬性賦值工作,或者傳遞關係,或者添加afterDelete,validate和afterSave方法來支持保存和刪除等,但是我希望這對我有用開始。

您也可以通過覆蓋行爲中基本模型的__get和__set方法來使其更好,以便如果請求子類型表中的列,它會透明地從文本表中獲取它,進行模式查找以獲取列名等。比在此示例中對其進行硬編碼更好。查看yiiext存儲庫中的EavBehavior和AdvancedArBehavior(或類似的)可以幫助您瞭解如何使其變得更加輕鬆。而不是每個子類型的行爲,你可以有一個通用的行爲,只需傳入子類型的表名。 (噢我真的喜歡那個)

乾杯!

+0

非常感謝m8 :)我不知道如果你的方式將適合我的環境,但肯定會深入調查,新的方式來做事情顯示:)我會不斷更新這方面的信息項目,如果你會發現更多的「提示」,我會很高興:) – canni 2010-08-26 19:29:16

+0

這是如何工作的?對做類似的事情感興趣 – 2011-02-05 19:03:02