0
class Assembly < ActiveRecord::Base 
    has_and_belongs_to_many :parts 
end 

class Part < ActiveRecord::Base 
    has_and_belongs_to_many :assemblies 
end 

In Konsole:Wie kann verhindert werden, dass die Option has_and_belongs_to_many Datensätze in Rails löscht?

part1 = Part.new 
assembly1 = Assembly.new 
assembly1.parts << part1 
part1.delete 
Parts.all 
=> [] 

assembly1.parts Überprüfung zeigt, dass es immer noch eine Beziehung

Wie ist das möglich, wenn der Datensatz gelöscht wurde. (!)?

Wie kann das Löschen von Teilen verhindert werden, die Baugruppen zugeordnet sind?

Arbeiten in Rails 3.0.7.

Antwort

2

Alles, was Sie hier getan haben, wurde aus dem Speicher gemacht (nichts wurde in der Datenbank gespeichert).

Die Methode ActiveRecord delete entfernt ein Objekt aus der Datenbank, sucht jedoch nicht nach anderen Objekten im Speicher, die möglicherweise bereits auf dieses Objekt verweisen. Ich denke, wenn Sie assembly1.parts.delete(part1) getan hätten, würde das wahrscheinlich tun, was Sie erwartet haben.

Wenn Sie die Objekte in die Datenbank gespeichert haben:

part1 = Part.create 
assembly1 = Assembly.create(:parts => [part1]) 
assembly1.parts 
# => [part1] 
part1.delete 
assembly1.parts 
# => [part1] 
assembly1.reload 
assembly1.parts 
# => [] 

Hinweis hier, wie auch wenn sie in der Datenbank ist wird part1.delete es nicht unbedingt von Ihrem Assembly-Objekt entfernen, bis Sie die In-Memory-Sammlung aktualisieren oder löschen Sie es mit dem Verfahren I bereits erwähnt assembly1.parts.delete(part1)

UPDATE

ich glaube, Sie in der Regel nicht dieverwenden solltenMethode. Sie sollten fast immer destroy() verwenden. delete() löscht nur ein Löschen in die Datenbank und ignoriert alle Rückrufe und ich glaube :dependent => :destroy -Style Deklarationen in Ihrem Modell. Wenn Sie die destroy() Methode verwenden, dann können Sie einen Rückruf before_destroy in Ihrem Modell erklären:

class MyClass 
    has_and_belongs_to_many :foos 

    before_destroy :allow_destroy 

    def allow_destroy 
    foos.empty? 
    end 
end 

, die Ihre Anforderungen nicht zu zerstören bekommen sollen, wenn sie Teil einer Baugruppe ist. Sie können nicht delete() von der Ausführung stoppen, weil es Rückrufe ignoriert: ActiveRecord::Relation#delete documentation

Mehr Infos über model callbacks (documentation)

0

Sie müssen :dependent => :destroy zum Controller hinzufügen.

+0

Eigentlich stattdessen die abhängigen Datensätze zu löschen, möchte ich die Löschaktion zum Scheitern verurteilt und den Grund zu blinken: „Kann nicht Teil löschen, da es wird von einer oder mehreren Baugruppen verwendet. " –