Schienen polymorphe Vereinigung (Legacy-Datenbank)
-
22-09-2019 - |
Frage
Ich bin mit einer Legacy-Datenbank, so dass ich habe keine Kontrolle über das Datenmodell. Sie verwenden eine Menge von polymorphen Link / JOIN-Tabellen, wie diese
create table person(per_ident, name, ...)
create table person_links(per_ident, obj_name, obj_r_ident)
create table report(rep_ident, name, ...)
wo obj_name
ist der Tabellenname und obj_r_ident
ist die Kennung.
So würde verknüpfte Berichte eingefügt werden:
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)
Und dann Person 1 würde 2 verknüpfte Berichte hat, 1 und 2.
kann ich mögliche Vorteile verstehen, um ein Datenmodell wie diese zu haben, aber ich meist ein großes Manko sehen: mit Einschränkungen nicht möglich ist, die Datenintegrität zu gewährleisten. Aber ach, ich kann das nicht mehr ändern.
Aber zu verwenden, um dies in Rails, ich war an diesen polymorphen Assoziationen aus, aber nicht eine schöne Art und Weise, diese zu lösen finden (da ich nicht die Spalten-Namen ändern kann, und habe ohne weiteres nicht einen Weg finden, das zu tun).
Ich habe mit einer Lösung obwohl kommen. Bitte geben Anregungen.
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
Dies funktioniert, aber ich frage mich, ob es wäre eine bessere Lösung, polymorphe Verbände mit.
Lösung
Sie können die Spaltennamen außer Kraft setzen, sicher, aber eine schnelle Scan des Rails-API hat mich nicht überall zeigen die polymorphe ‚Typ‘ Spalte außer Kraft zu setzen. Also, würden Sie nicht in der Lage sein, das zu auf ‚obj_name‘.
Es ist hässlich, aber ich denke, Sie HABTM in der Tabelle für jede Art von Objekt benötigen.
Sie Macht der Lage sein, so etwas zu tun:
{: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
Wenigstens auf diese Weise alle gängigen Sachen Aufenthalte DRY und Sie können leicht hinzufügen mehr Beziehungen.
Andere Tipps
Mindestens so von Rails 4.2.1, Sie foreign_type
auf eine belongs_to Erklärung passieren können den Namen der Spalte angeben, für den ‚Typen‘ verwendet werden, der polymorphen Assoziation
http://apidock.com/rails/v4.2.1/ Active / Verbände / Class / belongs_to