2010-12-20 4 views
3

Ich entwickle ein Projekt, wo ich eine Entität, die zwei Arten von Vermögenswerten haben kann: Bilder und Videos, im Grunde.Rails STI bedingte Sub-Classing von Basisklasse

Da ich mag, dass alle Vermögenswerte auf dem gleichen Tisch sein und ein einziges Upload-Formular entweder für Bilder oder Videos, ich bin mit Single Table Inheritance sowohl Bild mit und Video von der absteigend Anlage Klasse. Außerdem werde ich verschiedene Validierungen/Callbacks ausführen, je nachdem ob es sich um ein Video oder ein Bild handelt.

ich Büroklammer bin mit dem Upload-Vorgang befassen, und meine Idee ist, wenn Sie eine Datei hochladen und ein Asset mit ihm zu schaffen, wird die Anwendung der richtige Unterklasse (Bild oder Video) instanziiert je nach der Mime-Typ der hochgeladenen Datei.

Dies ist eine Skizze meiner Klassen:

class Project < ActiveRecord::Base 
    has_many :assets 
    accepts_nested_attributes_for :assets 
end 

class Asset < ActiveRecord::Base 
    belongs_to :project 
    has_uploaded_file :content, ... 
end 

class Picture < Asset 
    validate :image_size 
    ... 
end 

class Video < Asset 
    after_save :convert_format 
    ... 
end 

Meine Idee ist es, einen before_save Rückruf auf der Asset- Klasse zu implementieren und versuchen es die richtige Klasse zu instanziieren, aber ich bin nicht sicher, wie man mach es oder wenn es eine gute Idee ist.

Irgendeine Idee zu diesem Thema?

Antwort

1

Während Sie fette Modelle und dünne Controller bevorzugen sollten, scheint mir das besser in den Controller platziert. Mein primäres Grundprinzip ist, dass Sie in Ihrem Asset Modell einen Basistyp an seine Subtypen koppeln, was sich für mich nicht richtig anfühlt (obwohl ich sehe, dass APIs es immer tun).

+1

Ich akzeptiere diese Antwort, weil sie nahe an meine Arbeit heranreichte und mich in die richtige Richtung wies: Ich habe die geschachtelte Modellierungsfunktion verworfen und das verschachtelte Modell manuell gespeichert. Die "Fabrik" -Logik, die die richtige Unterklasse erzeugt, ist zwar im Projekt-Controller, aber sie kann leicht in ihr Modell portiert werden, was ich am Ende tun werde, sobald ich den Rest der wichtigen Sachen fertiggestellt habe. Ein vereinfachtes Snippet, das die Lösung darstellt, ist unter http://pastie.org/1522024 verfügbar. – punnie