2009-12-30 121 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