Frage

Ich verwende einzelne Tabelle Vererbung für meine Anwendung. Mein polymorpher Typ ist Wartung mit nur einem Subtyp, gerade jetzt, genannt Ölwechseln. Ich laufe Probleme meine Aufzeichnungen in meiner create-Methode in der Steuerung zu schaffen. Hier ist der Code.

@log = Log.new(params[:log])
@log.maintenance = Maintenance.new(params[:maintenance])

Die params [: Wartung] Hash hat Tasten {: Name,: type}. Ich kann ihre Existenz und Werte überprüfen, indem sie den Ausdruck wie folgt

print params[:maintenance][:name]
print params[:maintenance][:type]

Wenn ich in „Ölwechsel“ für den Wert des übergeben: Typenschlüssels ist das Wartungsprotokoll vom Typ Wartung und nicht den von Ölwechseln. Ich kann das überprüfen, indem Sie den Datensatz in der REPL Konsole zu finden. Das Typ-Feld ist gleich Null. Ich kann es funktioniert, wie ich möchte, indem Sie die folgende Zeile hinzufügen.

@log.maintenance.type = params[:maintenance][:type]

Aber das ist hässlich. Was ich frage mich ist, warum das nicht schaffen Methode, um das Typ-Feld gesetzt, wie es der Name Feld tut nur finden?

Die beiden Typen, die Sie in meinem schema.rb so aussehen zu sehen

create_table "logs", :force => true do |t|
  t.date     "date"
  t.text     "description"
  t.string   "title"
  t.string   "summary"
  t.integer  "car_id"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.integer  "maintenance_id"
  t.integer  "mileage"
end

create_table "maintenances", :force => true do |t|
  t.string   "name"
  t.string   "type"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "oil_brand"
  t.string   "oil_type"
  t.string   "oil_filter_type"

Meine Modelle wie folgt aussehen.

class Log < ActiveRecord::Base
belongs_to :car
has_and_belongs_to_many :tags
  belongs_to :maintenance
end

class Maintenance < ActiveRecord::Base
  has_one :log
end

class OilChange < Maintenance
end

TIA!

War es hilfreich?

Lösung

Die spezifische Antwort ist, dass das type Attribut, wie viele Rails des besonderen Eigenschaften von Massenzuordnung geschützt ist. (Look up :attr_protected in der Dokumentation.)

Die Antwort auf das allgemeinere Problem ist, dass Sie nicht Ihre Modelle genug zu vertrauen. Wenn Sie einen Datensatz vom Typ Ölwechsel erstellen möchten, sollten Sie nicht Maintenance.new oder Maintenance.create nennen. Rufen Sie OilChange.new oder OilChange.create statt und Rails kümmert sich automatisch um die Art der Einstellung und tun all die Hintergrundarbeit für Sie.

Andere Tipps

Versuchen Sie, den folgenden Code:

begin
  klass = Module.const_get(params[:maintenance][:type])
  @log.maintenance = klass.new(params[:maintenance])
  if ! @log.maintenance.is_a?(Maintenance)
    @log.maintenance = Maintenance.new(params[:maintenance])
  end
rescue NameError
  @log.maintenance = Maintenance.new(params[:maintenance])
end

Wenn Sie nur Subklassen von Wartung in Ihrer Datenbank haben wollen, gehen Sie wie folgt in Ihrer Wartungsklasse:

class Maintenance < ActiveRecord::Base
  validates_presence_of :type
  # other stuff goes here
end

Dieser Code wird eine ungültige Wartungs Klasse erstellen, wenn die params die falsche Art enthalten. Wenn sie die richtige Art, eine Instanz der angegebenen Klasse enthalten wird erstellt.

Wenn Sie Ihre Modelle Namespaces verwenden können Sie diesem Artikel schauen in anstelle von Module.const_get:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top