3 votes

:dependent => :destroy n'appelle pas la méthode de destruction avant la suppression ?

J'ai un modèle de note, avec l'association suivante

note.rb

has_many :note_categories, :dependent => :destroy
has_many :categories, :through => :note_categories

Le modèle NoteCategory a été créé pour servir de table de jonction entre les notes et les catégories. Au départ, il s'agissait simplement d'un modèle/table, mais j'ai créé un contrôleur pour effectuer des opérations personnalisées lorsque quelqu'un supprime une catégorie d'une note.

note_categories_controller.rb

def destroy
    p "in notes_categories_controller destroy"
    note_category_to_delete = NoteCategory.find(params[:id])
    #some custom stuff
    note_category_to_delete.destroy
    respond_to do |format|
        format.html { redirect_to(notes_url }
        format.xml  { head :ok }
    end
end

Cela fonctionne bien, car je peux utiliser ce lien pour créer un bouton qui supprimera une catégorie d'une note :

<%= button_to 'Remove', note_category, :confirm => 'Are you sure?', :controller => :note_categories, :method => :delete %>

et cela fonctionne bien.

Le problème est que lorsque je supprime une note, les rangées note_category qui appartenaient à la note sont supprimées, mais la méthode de destruction n'est pas exécutée. Je le sais parce que le code personnalisé n'est pas exécuté et que la sortie de la première ligne ne s'affiche pas dans le terminal. Voici la sortie du terminal :

Note Load (0.7ms)   SELECT * FROM "notes" WHERE ("notes"."id" = 245) 
NoteCategory Load (0.5ms)   SELECT * FROM "note_categories" WHERE ("note_categories".note_id = 245) 
NoteCategory Destroy (0.3ms)   DELETE FROM "note_categories" WHERE "id" = 146
Note Destroy (0.2ms)   DELETE FROM "notes" WHERE "id" = 245

Je pensais qu'en utilisant :dependent => :destroy, la méthode de destruction dans le contrôleur NoteCategories devait s'exécuter avant la suppression. Qu'est-ce qui ne va pas ?

4voto

jerhinesmith Points 5425

:dependent => :destroy appellera la méthode de destruction du modèle pas le contrôleur .

A partir de la la documentation :

Si la valeur est :destroy, tous les objets associés sont détruits en même temps que cet objet en appelant leur méthode de destruction.

En d'autres termes, si vous souhaitez que vos catégories de notes soient personnalisées avant d'être détruites, vous devrez soit surcharger la fonction destroy dans votre NoteCategory modèle ou utiliser un callback after_destroy/before_destroy.

Quoi qu'il en soit, l'utilisation de :dependent => :destroy n'exécutera jamais le code contenu dans votre contrôleur, c'est pourquoi vous ne voyez pas la sortie de la fonction puts dans le terminal.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X