2010-07-31 56 views
4

用下面(簡化)MySQL表定義:如何建立與DBIx :: Class的is-a關係?

create table items (
    item_id   int unsigned auto_increment primary key, 
    purchase_date date 
    ) engine = innodb; 

create table computers (
    item_id   int unsigned primary key, 
    processor_type varchar(50), 
    foreign key item_fk (item_id) references items (item_id) 
     on update restrict on delete cascade 
    ) engine = innodb; 

create table printers (
    item_id   int unsigned primary key, 
    is_duplex  boolean, 
    foreign key item_fk (item_id) references items (item_id) 
     on update restrict on delete cascade 
    ) engine = innodb; 

作爲新DBIx::Class,我想Model數據庫實體之間的繼承關係(計算機和打印機均爲項目),但所提供的belongs_to的關係類型,這似乎很尷尬,因爲與基類的關聯沒有隱藏,所以必須爲這兩個類手動創建實體,並且在派生類中訪問基類屬性與訪問它們自己的屬性不同。

有一種優雅的解決方案,它可以讓我說:

$printer = $printer_rs->create({purchase_date => $date, is_duplex => 0}); 

或(在已取得的打印機行):

$date = $printer->purchase_date; 
$duplex = $printer->is_duplex; 

回答

6

可以使用proxy屬性上的關係,使存取 - 它的記錄中的DBIx::Class::Relationship::Baseadd_relationship,您可以用belongs_to這樣使用它:

__PACKAGE__->belongs_to(
    'item' => 'MyApp::Schema::Item', 
    'item_id', 
    { proxy => [ qw/purchase_date/ ] } 
); 

這將使所有的打印機對象有purchase_date引用相關Item對象的訪問器。

至於創建,你不能不覆蓋new_result,這實際上很容易。你只需要利用創建,從相關行爲的轉向

->create({ 
    is_duplex => 1, 
    purchase_date => $dt, 
}) 

->create({ 
    is_duplex => 1, 
    item => { 
    purchase_date => $dt, 
    }, 
}) 

或者您也可以強加給的是什麼列item關閉對用戶的知識和有他們直接提供hashref;)