Warum kann ich Record.all.destroy in Rails nicht verwenden?

7

Ich lerne gerade Ruby und das Ruby on Rails-Framework. Ich habe festgestellt, dass ich in der Tabelle records einen Datensatz mit einer ID von 5 finden und ihn mit dem folgenden Code löschen kann:

Record.find(5).destroy

Das macht Sinn - ich ketten Methoden, um die Aufzeichnung zu finden und sie zu zerstören. Wenn ich jedoch alle Datensätze in der Tabelle zerstören möchte, wäre der logische Befehl der folgende, da der all Selektor alle Datensätze in der Tabelle auswählt:

Record.all.destroy

Und das bringt einen NoMethodError zurück! Mir ist bewusst, dass ich Record.destroy_all oder Record.delete_all verwenden kann, um diese Aufgabe zu erfüllen, aber ich würde gerne wissen, warum ich nicht einfach die logischste Wahl verwenden kann, anstatt Dinge wie delete_all nachschlagen zu müssen. Ich bin neu in diesem Rahmen, also ist es durchaus möglich, dass ich hier etwas Grundlegendes vermisse.

Danke für etwaige Antworten im Voraus.

    
element119 30.05.2011, 16:04
quelle

5 Antworten

14

Es war eine Designentscheidung. DataMapper nahm Ihre Vorgehensweise . Das explizite Schreiben von destroy_all kann mühsam sein, verhindert aber auch, dass Sie etwas tun, was Sie wirklich nicht wollen (d. H. Alles in einer Tabelle löschen, wie x = User; ...; x.destroy ).

    
Marcel Jackwerth 30.05.2011, 16:14
quelle
3

Ich stimme zu, dass es logisch wäre, dies tun zu können. Technisch betrachtet gibt Record.all eine Sammlung (oder einen Proxy für eine Sammlung) zurück, die die Methode destroy nicht implementiert.

    
Jits 30.05.2011 16:15
quelle
1

Wenn Sie

haben %Vor%

Dies gibt ein Record-Objekt / eine Record-Instanz zurück, die die Daten in einer Zeile in Ihrer Tabelle darstellt. Dann rufen Sie die Methode # destroy für das Objekt auf, das von Ihrem Datensatzmodell definiert wird.

Wenn Sie

haben %Vor%

Dies gibt ein Array-Objekt zurück. Damit du #destroy auf dem Array aufrufen kannst, musst du Rubys Kern-Array-Klasse mit einer #destroy-Methode versehen.

    
monocle 30.05.2011 16:19
quelle
1

Der einfachste Weg, Record.destroy_all zu vermeiden, wäre Record.all.each {|r| r.destroy} . Dies kann Ihre API-Design-Einstellungen etwas zufriedenstellen, sollte aber viel langsamer als die erste Option sein.

    
user94154 30.05.2011 16:24
quelle
0

Eigentlich kannst du (in gewisser Weise). Da .all ein Array und keine aktive Datensatzrelation zurückgibt, was genau würden Sie löschen? Ich würde nicht sagen Record.all.destroy ist überhaupt logisch - löschen Sie das Array-Objekt?

Eine Sache, die Sie tun könnten, ist das resultierende Array abzubilden, und da map einen proc ( & ) akzeptiert, können Sie diesen proc für jedes Objekt in Ihrem Array ausführen.

%Vor%

Beachten Sie, dass dadurch Rückrufe für alle Ihre Objekte ausgelöst werden, die langsamer als beabsichtigt sein könnten. Wenn Sie vermeiden möchten, Callbacks auszulösen, können Sie die entsprechende destruktive Methode zuordnen, anstatt sie zu zerstören. (Hinweis:: löschen)

Alternativ könnten Sie auch einfach Folgendes tun:

%Vor%

wie Sie in Ihrer Frage angegeben haben.

    
saneshark 22.10.2013 13:18
quelle

Tags und Links