Frage

Ich habe eine Form, die ich Dateien verschiedenen Formate in einen Stream hinzufügen kann. So wird ein Strom von vielen Dateien aus, sind diese Dateien XML-Dateien, aber im Grunde haben unterschiedliche Schemata. Ich ein Formular, das dem Benutzer erlaubt, zu addieren, was Datei, die sie wollen, ich bin mit STI (die großen Werke, wenn die Daten bereits in der Tabelle ist), mein Problem ist, die Daten in der Tabelle hinzugefügt wird.

Die Form hat 1 Eingabefeld, um nur file_field, dass der Benutzer die Datei, die sie hochladen möchten. Da ich mir das richtige Objekt instanziiert nicht in der Lage bin nur eine Form habe, muß ich es programmatisch tun .. und ich bin nicht sicher, wie es zu tun.

Muss ich gerade (oder kann ich) in eine Drop-Down mit den möglichen Typen, und rufen Sie das Feld ‚Typ‘, so dass, wenn das Formular Schienen vorgelegt wird, den Schreibobjekttyp instanziiert, da das type-Attribut versehen ist?

Was ist die beste Praxis für diesen .. Ich bin mit Schienen 2.3.4.

War es hilfreich?

Lösung

fand ich eine Lösung unter http://coderrr.wordpress.com/2008/04/22/building-the-right-class-with-sti-in-rails/#comment-1826

class GenericClass < ActiveRecord::Base
  class << self
    def new_with_cast(*a, &b)
      if (h = a.first).is_a? Hash and (type = h[:type] || h['type']) and (klass = type.constantize) != self
        raise "wtF hax!!"  unless klass < self  # klass should be a descendant of us
        return klass.new(*a, &b)
      end

      new_without_cast(*a, &b)
    end
    alias_method_chain :new, :cast
  end
end

Was für mich mit minimalem Code super funktionierte - ich weiß nicht, ob seine hackish oder nicht, aber es funktioniert, und ist ziemlich sauber. Ich mochte die Tatsache, dass seine nur 10ish Zeilen Code.

Andere Tipps

Ich weiß nicht, wie viele Typen, die Sie haben, aber ich habe einfach separate Controller und Ansichten für die verschiedenen Typen in der Vergangenheit verwendet. Auf diese Weise kann nicht neues Objekt der Basisklasse erstellen und versuchen, die Art zu setzen, verwenden Sie nur das Modell, das erbt von der Basisklasse. Jede neue / Edit-Seite für Ihre Ressourcen können einen gemeinsamen Teil im form_for Block übertragen. Die teilweise enthalten würde Ihre file_field.

Auf diese Weise, wenn das Formular abgeschickt wird, wird es auf den richtigen Controller geht, rief die richtige resource.new und alles in Ordnung ist.

Der Nachteil ist natürlich mehr Dateien und was Seite Sie eine Verknüpfung zu „neuen Datei hinzufügen“ auf mehrere Links wie „add new diese Art der Datei“, „add new dass Dateityp“ usw. hinzufügen müssen

Wie für den Typ in der Form eingestellt wird, ob ich bin mir nicht sicher, das funktioniert, ich bezweifle es, aber es nur einen Versuch geben (Lassen Sie uns wissen). Man könnte diese Art Dropdown eine select_tag machen und wenn geändert Verwendung Javascript um die Aktion Position auf dem Formular zu ändern.

Herausgegeben und hinzugefügt grundlegende Arbeit um

Nicht, dass ich wie diese Lösung und ich bezweifle, sein keineswegs die beste, aber wenn Sie wirklich nicht wollen, getrennte Regler, und Sie müssen, um es arbeiten Sie so etwas tun könnten:

class XmlFile < ActiveRecord::Base
end

class XmlFileTypeA < XmlFile 
end

class XmlFileTypeB < XmlFile 
end

def create
    # Leaving this case statement in the controller for simplicity but you probably want to move this to the model
    case params[:chosen_xml_type]
      when "file_type_a"
        @item = XmlFileTypeA.new(params)
      when "file_type_b"
        @item = XmlFileTypeB.new(params)
      else
        raise "Unknown file type!"
      etc
    end
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top