2017-10-14 8 views
0

Wir haben eine Rails App, die 2 Modelle verwendet: Bild und Video. Sie gehören beide zu einer Collection-Entity. Was passiert ist, wenn wir beide Arten einheitlich abfragen oder verwenden wollen - wir können nicht. Wenn wir also die letzten 15 holen wollen, fragen wir zweimal und sortieren dann und nehmen dann die 15 wieder. Wenn wir (ID) finden möchten, müssen wir immer bekommen, welcher Typ es ist - Video oder Bild ...Entwerfen einer polymorphen Klasse

Also haben wir darüber nachgedacht, wie man das löst. Besteht ein Asset-Modell, das auf eins zeigt? Kann es geladen werden?

In meiner Vision muss es Asset.find (_id) sein und ich werde entweder Bild oder Video agnostisch bekommen.

Was ist der einfachste oder korrekteste Weg, dies in Rails zu lösen?

Danke!

+0

Ich denke 'enum' in Schienen ist, was Sie suchen. http://api.rubyonrails.org/v5.1/classes/ActiveRecord/Enum.html. Ich hoffe das hilft. – thanhnha1103

+0

Es gibt keine korrekte Möglichkeit, dies zu lösen, da es ein Beispiel für [Objektrelationale Impedanzabweichung] ist (https://en.wikipedia.org/wiki/Object-relational_impedance_mismatch). Übliche Wege, dies zu lösen, sind die Vererbung einzelner Tabellen oder mehrerer Tabellen. – max

+0

Mit STI, wie von Tamer beschrieben, können Sie MediaItem.find (id) ausführen und je nach Ergebnis ein Video- oder Bildmodell erstellen. – s1mpl3

Antwort

1

Sie könnten Single Table Inheritance verwenden, um dieses Ziel zu erreichen.

Angenommen, Sie haben ein Modell Media genannt:

rails g model media_item type:string <other attributes here> 

Dann erben Sie von ihm zwei Modelle: Video und Image, wie folgt aus:

rails g model video --parent=MediaItem 
rails g model image --parent=MediaItem 

Jetzt in Ihrer Modelle:

class MediaItem < ApplicationRecord 
    belongs_to :collection 
end 

class Collection < ApplicationRecord 
    has_many :media_items 
end 

Dieser Ansatz kommt mit Som Aber Nachteile. Zum Beispiel können Unterklassen viele verschiedene Attribute haben, und Sie könnten am Ende zu viele Attribute haben, die in einer Unterklasse verwendet werden, aber nicht die andere, und umgekehrt.

Es gibt einige Problemumgehungen dafür, wie ein properties Feld, das Hash-ähnlich ist und Unterklassen-spezifische Attribute enthält. Dies kann jedoch auch problematisch werden, wenn Sie eine bestimmte Eigenschaft indizieren müssen und Ihre Datenbank solche Indizes nicht unterstützt. Oder Sie könnten einfach eine separate Tabelle für jede Unterklasse mit 1-zu-1-Beziehung erstellen, eine Art, die als Vererbung mehrerer Tabellen bekannt ist, aber dies hat auch seine Nachteile. Alles hängt von Ihrem speziellen Anwendungsfall ab.

+2

"Oder Sie können einfach eine separate Attributtabelle für jede Unterklasse mit 1-zu-1-Beziehung erstellen . " - Das wird häufig als Vererbung mehrerer Tabellen bezeichnet. – max

+0

@max Vielen Dank, ich wusste eigentlich nicht, dass es einen Namen hat lol. Wird die Antwort entsprechend aktualisieren. –

+0

Ich suche nach den Modellen, die ich jetzt habe. Was Sie vorschlagen, ist, dass ich meine ganzen Modelle und App zu MediaItem konvertieren soll. – Himberjack

Verwandte Themen