2008-12-01 11 views
64

Ich weiß, dass dies wahrscheinlich im Internet irgendwo ist, aber ich kann die Antwort hier auf Stackoverflow nicht finden, also dachte ich, ich könnte die Wissensbasis hier ein wenig aufwerten.Kann ich Cascade löschen in Rails einrichten?

Ich bin ein Neuling zu Ruby and Rails, aber meine Firma wird ziemlich in es investiert, so dass ich versuche, es in ein wenig mehr Details kennen zu lernen.

Es war schwierig für mich, meine Denkweise zu ändern, um eine Anwendung aus dem "Modell" eher aus der Datenbank zu entwickeln, also versuche ich herauszufinden, wie ich all die Designarbeiten machen würde, die ich klassisch gemacht habe die Datenbank im Rails-Modell.

Die letzte Aufgabe, die ich mir selbst gegeben habe, ist herauszufinden, wie man ein Rails-Datenbankmodell für kaskadierende Löschungen konfiguriert? Gibt es eine einfache Möglichkeit, dies zu tun? Oder müsste ich in die MySql gehen und das einrichten?

Danke.

-Matt

Antwort

79

Sie können auch die: abhängige Option zu: delete_all. : delete_all wird eine einzelne SQL-Anweisung ausgeben, um alle untergeordneten Datensätze zu löschen. Aus diesem Grund können Sie mit delete_all eine bessere Leistung erzielen.

has_many :memberships, dependent: :delete_all 
+8

Ihre Erklärung ist verwirrend. Eine einzelne SQL-Anweisung wird verwendet, aber die Methode destroy wird nicht für jede untergeordnete Zeile aufgerufen. Sie müssen dafür den_destroy_all verwenden. –

+0

@John - hoffe, dass die Änderungen die Verwirrung klären. Danke, dass du das gezeigt hast. –

+0

@Mike - viel besser, danke. –

58

Ja, Sie können, wenn Sie eine Beziehung wie has_many verwenden Sie dies nur tun

has_many :memberships, dependent: :destroy 
+0

Dan, gelöscht Ich denke also, meine nächste Frage ist, ob ich einen db migrate-Befehl ausführen werde, der das tatsächlich in der db einrichtet?Oder wird die Kaskadierung komplett über Schienen abgewickelt? –

+0

Ja, es wird von Schienen gehandhabt. (Stellen Sie jedoch sicher, dass Sie wirklich immer alle verwandten Zeilen löschen müssen.) –

+0

@Matt - Die has_many-Zeile sollte in Ihrer Modellklasse enthalten sein, die Migration fügt das nicht für Sie hinzu. – Gareth

6

Es sieht aus wie dieses Plugin können Sie geben, was Sie suchen, wenn Sie wollen die kaskadierende Löschungen in der eigentlichen Datenbankstruktur wider:

http://www.redhillonrails.org/foreign_key_migrations.html

Format hierfür wäre in einer Migration mit somethi ng wie folgt:

create_table :orders do |t| 
    t.column :customer_id, :integer, :on_delete => :set_null, :on_update => :cascade 
    ... 
end 
+5

Dieser Link ist tot, aber das ist eine neuere Alternative: http://github.com/matthuhiggins/foreigner – gdelfino

9

Denken Sie daran, die auf den untergeordneten Datensätze DELETE_ALL werden alle Rückrufe nicht ausführen (wie before_destroy und after_destroy).

9

Entgegen der angegebenen Antwort empfehle ich sehr, dies auch auf Datenbankebene zu tun. Falls Sie verschiedene Prozesse oder eine Multi-Thread-Umgebung haben, kann es vorkommen, dass Datensätze nicht ordnungsgemäß gelöscht werden. Darüber hinaus macht der Datenbank-Fremdschlüssel beim Löschen vieler Daten viel schneller.

Wie in der vorgeschlagenen Antwort dies zu tun:

has_many :memberships, dependent: :delete_all 

jedoch auch ein foreign_key in einer Migration auf Setup stellen Sie sicher. Auf diese Weise sorgt die Datenbank dafür, dass die Datensätze automatisch für Sie gelöscht werden.

Um die Werte zunichte machen, wenn eine Mitgliedschaft gelöscht wird, vorausgesetzt, Sie ein Benutzermodell haben:

add_foreign_key :users, :memberships, on_delete: :nullify 

Sie auch alle Modelle löschen können, wenn eine Mitgliedschaft

add_foreign_key :users, :memberships, on_delete: :cascade 
Verwandte Themen