2009-12-30 127 views
4

我使用的是舊數據庫,因此我無法控制數據模型。他們使用了大量的多態鏈接/加入-表,這樣rails多態關聯(遺留數據庫)

create table person(per_ident, name, ...) 

create table person_links(per_ident, obj_name, obj_r_ident) 

create table report(rep_ident, name, ...) 

其中obj_name是表名,obj_r_ident是標識符。 所以鏈接報表將被插入如下:

insert into person(1, ...) 
insert into report(1, ...) 
insert into report(2, ...) 

insert into person_links(1, 'REPORT', 1) 
insert into person_links(1, 'REPORT', 2) 

然後人1人有2個鏈接報表,1和2

我可以理解這樣的數據模型可能帶來的好處,但我主要是看一個很大的缺點:使用約束不可能確保數據的完整性。但是,唉,我不能再改變這個了。

但是爲了在Rails中使用它,我在尋找多態關聯,但沒有找到一個很好的方法來解決這個問題(因爲我無法更改列名稱,也沒有找到方法來做到這一點)。

雖然我確實想出了一個解決方案。請提供建議。

class Person < ActiveRecord::Base 

    set_primary_key "per_ident" 
    set_table_name "person" 
    has_and_belongs_to_many :reports, 
         :join_table => "person_links", 
         :foreign_key => "per_ident", 
         :association_foreign_key => "obj_r_ident", 
         :conditions => "OBJ_NAME='REPORT'" 
end 

class Report < ActiveRecord::Base 

    set_primary_key "rep_ident" 
    set_table_name "report" 
    has_and_belongs_to_many :persons, 
        :join_table => "person_links", 
        :foreign_key => "obj_r_ident", 
        :association_foreign_key => "per_ident", 
        :conditions => "OBJ_NAME='REPORT'" 
end 

這可行,但我想知道是否會有更好的解決方案,使用多態關聯。

回答

1

當然,你可以覆蓋列名,但是對Rails API的快速掃描沒有讓我看到覆蓋多態「類型」列的任何地方。所以,你將無法將其設置爲'obj_name'。

這很醜陋,但我認爲你需要一個HABTM用於表格中的每種類型的對象。

可能能夠做這樣的事情:

{:report => 'REPORT'}.each do |sym, text| 
    has_and_belongs_to_many sym, 
    :join_table => "person_links", 
    :foreign_key => "obj_r_ident", 
    :association_foreign_key => "per_ident", 
    :conditions => "OBJ_NAME='#{text}'" 
end 

至少這樣所有常見的東西,保持DRY,你可以很容易地添加更多的關係。

+0

事實上我沒有找到任何方法來重寫多態類型列。我希望這是我沒有看向正確的方向:)我喜歡你的建議。 – nathanvda 2009-12-31 10:05:31

+0

您可能可以破解ActiveRecord並覆蓋該列名稱,但是...... blech。 – wesgarrison 2009-12-31 17:44:40