Frage

Um genauer zu sein, "Wie kann ich bestätigen, dass ein Modell mindestens x gültig zugehörige Modelle erfordert geschaffen werden?" . Ich habe versucht, verschachtelte Modelle zu validieren, die als Mutter in der gleichen Form erstellt bekommen (und zeigen schließlich sofort Validierungen a la jQuery). Als beliebtes Beispiel kann die folgenden Modelle und Schema übernehmen.

class Project
  include DataMapper::Resource

  property :id,     Serial
  property :title,  String, :nullable => false

  has 2..n, :tasks
end

class Task
  include DataMapper::Resource

  property :id,         Serial
  property :project_id, Integer,  :key => true
  property :title,      String,   :nullable => false

  belongs_to :project
end

Alle Validierungen sind in den Schemadefinitionen erfolgen, wie Sie sehen können. Das wichtige ist hier „has 2..n, :tasks“. Diese Validierung tatsächlich funktioniert normalerweise gegeben, dass die verschachtelte Task-Attribute im params-Hash produzieren gültig Aufgaben. Wenn sie produzieren eine ungültig Aufgabe, aber dann wird nicht die Aufgabe bekommen erstellt und Sie werden mit einem Projekt am Ende, die weniger als zwei Aufgaben hat, und damit eine ungültig Projektobjekt.

Wie ich es verstehe, ist dies, weil es nicht herausfinden kann, wenn die Aufgabe Attribute gültig sind oder nicht, bis sie die Aufgaben zu retten versucht, und da - soweit ich weiß - die Aufgaben können nicht vor dem Projekt gerettet werden, ist das Projekt nicht bewusst, wenn die Aufgaben gültig sind oder nicht. Bin ich richtig in der Annahme, dies?

Wie auch immer, ich hatte gehofft, es würde eine schnelle Antwort, aber es scheint viel weniger trivial dann hatte ich gehofft. Wenn Sie Vorschläge haben überhaupt, das würde sehr geschätzt werden.

War es hilfreich?

Lösung

Ich fand eine schöne Lösung, die hier über die Transaktionen in DataMapper. Grundsätzlich ist dieser Transaktion versucht, das übergeordnete Objekt sowie alle untergeordneten Objekte zu speichern. Sobald man speichern ausfällt, dann wird die Transaktion beendet und nichts geschaffen wird. Wenn alles gut geht, werden die Objekte erfolgreich speichern.

class Project
  def make
    transaction do |trans|
      trans.rollback unless save
      tasks.each do |task|
        unless task.save
          trans.rollback
          break
        end
      end
    end
  end
end

Dies stellt sicher, dass alles, was gültig ist, bevor es alles gespeichert wird. Ich brauche nur zu meinen #save und #update Methoden ändern in meinem Controller-Code #make.

Andere Tipps

SET CONSTRAINTS ABGEGRENZTE könnte nützlich sein, wenn die Datenbank-Engine, die unterstützt wird.

Ansonsten schreibe vielleicht eine gespeicherte Prozedur, die Einsätze zu tun, und dann sagen, dass es das resonsibility der gespeicherten Prozedur, um sicherzustellen, dass nur korrekte, validierten Daten eingefügt wird.

Es ist ein Modell, Methode valid?, die Validierungen auf einem Modellobjekt ausgeführt wird, bevor es gespeichert wird. So ist die einfache Möglichkeit, die Assoziationen zu validieren wäre validates_with_block' or 'validates_with_method zu verwenden, um die Validierungen auf den Verbänden zu überprüfen.

Es wäre etwa so aussehen

validates_with_block do
  if @tasks.all?{|t|t.valid?}
    true
  else
    [false, "you have an invalid task"]
  end
end

Oder Sie könnten sehen dm-Verband-Validator oder dm-akzeptiert-nested-Attribute

Edit: für zusätzliche verrückt. laufen Validierungen auf die Aufgaben, dann überprüfen, um zu sehen, ob die Fehler nur diejenigen zur Vereinigung in Zusammenhang stehen.

validates_with_block do
  if @tasks.all?{|t|t.valid?;!t.errors.any?{|e|e[0]==:project}}
    true
  else
    [false, "you have an invalid task"]
  end
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top