2009-12-30 10 views
4

J'utilise une base de données héritée, donc je n'ai aucun contrôle sur le modèle de données. Ils utilisent beaucoup de lien polymorphes/join-tables, comme celui-cirails association polymorphe (base de données héritée)

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 est la table nom et obj_r_ident est l'identifiant. Ainsi, les rapports liés seraient insérés comme suit:

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) 

Et personne 1 aurait 2 rapports liés, 1 et 2.

Je peux comprendre les avantages possibles ayant une datamodel comme ça, mais je vois la plupart du temps un gros défaut: l'utilisation de contraintes n'est pas possible pour garantir l'intégrité des données. Mais hélas, je ne peux plus changer ça. Mais pour l'utiliser dans Rails, je regardais les associations polymorphes mais je n'ai pas trouvé de bonne façon de résoudre cela (puisque je ne peux pas changer les noms des colonnes, et je n'ai pas trouvé de moyen de le faire).

J'ai quand même trouvé une solution. S'il vous plaît fournir des suggestions.

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 

Cela fonctionne, mais je me demande s'il y aurait une meilleure solution, en utilisant des associations polymorphes.

Répondre

1

Vous pouvez remplacer les noms de colonnes, bien sûr, mais une analyse rapide de l'API Rails ne m'a montré nulle part pour remplacer la colonne 'type' polymorphe. Donc, vous ne seriez pas en mesure de mettre cela à 'obj_name'.

C'est moche, mais je pense que vous aurez besoin d'un HABTM pour chaque type d'objet dans votre table.

Vous pourriez être en mesure de faire quelque chose comme ceci:

{: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 

Au moins de cette façon toutes les choses communes reste DRY et vous pouvez facilement ajouter plus de relations.

+0

En effet i n'a trouvé aucun moyen de surcharger la colonne de type polymorphique non plus. J'espérais que ce n'était pas moi qui regardais dans la bonne direction :) J'aime ta suggestion. – nathanvda

+0

Vous pouvez peut-être pirater ActiveRecord et remplacer ce nom de colonne, mais ... blech. – wesgarrison