2013-05-27 6 views
19
person = Person.find(4123) 
person.destroy #=> false 

Auf welche Weise muss ich herausfinden, warum der Datensatz nicht gelöscht wurde? Das Modell verfügt über zwei Validierungen, beide werden nur bei create ausgelöst. Es hat einen Rückruf, aber der Rückruf wird nicht blockiert, wenn es fehlschlägt.Wie finde ich heraus, warum ich einen Datensatz nicht #destroy() kopieren konnte?

Ich habe keine Rückverfolgung oder Fehler zu sehen.

+0

Welche Schienen sind Sie? Bitte posten Sie Ihr Personenmodell. – zeantsoi

Antwort

20

ich in das gleiche Problem lief und hier ist, was ich habe, um herauszufinden, getan, was los ist ...

Zuerst für die Klasse des Objekts ich zu zerstören bin versucht, ich das Bild lief Sie heraus, was alle Verbände eingestellt, wie dependent: :destroy:

ary = Klass.reflect_on_all_associations 
      .select { |a| a.options[:dependent] == :destroy } 
      .map(&:name) 

Dann rief ich jedes der in ary auf meinem Objekt mit dem Namen Verbände und sammelte die Ergebnisse. Dies schränkt die Assoziation Namen nur diejenigen, die tatsächlich abhängige Objekte haben:

ary.select! { |a| obj.send(a).any? } 

Dann kann ich versuchen, jedes der Objekte durch diese Assoziation Namen zurückgegeben zu zerstören:

destroy_me = obj.send(ary[0]).first 
destroy_me.destroy 

Ich hatte nur ein Objekt so Das obige war genug, um die Zerstörung zum Scheitern zu bringen. Ich konnte dann auf dem Fehler auf dem Objekt suchen, die zerstören fehlgeschlagen:

destroy_me.errors 

Und das ist, wo ich endlich den Fehler sah, dass die Zerstörung verursacht wurde zum Scheitern verurteilt. Von dort war es eine einfache Sache der Programmierung (SMOP), um das Problem zu beheben.

In meinem Fall gab es einen before_destroy Rückruf, der verhindert, dass das Zerstören an einer meiner abhängigen Objektverknüpfungen funktioniert. Um das Debuggen in der Zukunft einfacher zu machen, habe ich beschlossen, einen Fehler in der Rails-Protokollierung bei fehlgeschlagenen Callbacks zu protokollieren (zusätzlich zum Hinzufügen der Fehlermeldung zu errors.base).

+0

Danke, hat mir sehr geholfen !! In meinem Fall hatte ich in der 'before_destroy'-Methode einfach' return false', was die Zerstörung des Objekts verhinderte. – guyaloni

+1

Ich bin etwas verwirrt durch den 2. Codeblock. Wie es jetzt ist, würde es entweder alle oder keine der Assoziationen in & ldquor; ary "auswählen, abhängig davon, ob das Objekt eine der ersten Assoziationen hatte. Sollte es "ary.select" sein! {| a | obj.send (a) .irgendein? } 'stattdessen? – Aaron

2

In welcher Version sind Sie unterwegs? In Rails 4 können Sie eine Zerstörung mit person.destroy! erzwingen. Wenn die Aktion fehlschlägt, wird eine Rückverfolgung angezeigt.

+0

Das ist richtig, das wird eine ActiveRecord :: RecordNotDestroyed-Ausnahme –

+0

Rails 3.2 gerade jetzt, nicht wirklich bereit für ein Upgrade. – krainboltgreene

+0

Das ist in Ordnung, aber können Sie bitte Ihre Frage auf Ihr 'Person' Modell erweitern? – zeantsoi

0

Sie sollten Debug-Informationen hinzufügen, z. logger.debug und schau dir deine Log-Dateien an. z.B. log/production.log wenn es im Produktionsmodus läuft und so weiter und du solltest herausfinden warum. Wenn nicht, können Sie den relevanten Abschnitt der Protokolldatei (z. B. die Aktion, die Sie gerade ausführen) hier hochladen und wir können Ihnen weiterhelfen.

+1

Wohin würden Sie sogar Log-Anweisungen schreiben, um das zu erfassen? – krainboltgreene

2

Dieser Fehler tritt normalerweise auf, weil dependent: :restrict_with_error für eine Zuordnung im Modell angegeben wurde. Führen Sie in Ihrer Modelldefinition (sowie den zugehörigen Modelldefinitionen) eine Schnellsuche durch, und prüfen Sie, ob dies der Fall ist.

Verwandte Themen