Supprimer en cascade dans les modèles Ruby ActiveRecord?

Je suivais le screencast sur rubyonrails.org (création du blog).

J’ai des modèles suivants:

comment.rb

class Comment < ActiveRecord::Base belongs_to :post validates_presence_of :body # I added this end 

post.rb

 class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments end 

Les relations entre les modèles fonctionnent bien, sauf pour une chose: lorsque je supprime un enregistrement de publication, je m’attendrais à ce que RoR supprime tous les enregistrements de commentaires connexes. Je comprends qu’ActiveRecords est indépendant de la firebase database, il n’y a donc pas de méthode intégrée pour créer des instructions sur les clés étrangères, les relations, ON DELETE, ON UPDATE. Y a-t-il un moyen d’y parvenir (peut-être que RoR lui-même pourrait se charger de supprimer les commentaires connexes?)?

Oui. Sur un modèle d’association de Rails, vous pouvez spécifier l’option :dependent dependive, qui peut prendre l’une des trois formes suivantes:

  • :destroy/:destroy_all Les objects associés sont détruits à côté de cet object en appelant leur méthode destroy
  • :delete/:delete_all Tous les objects associés sont détruits immédiatement sans appeler leur méthode :destroy
  • :nullify Toutes les clés étrangères des objects associés sont définies sur NULL sans appeler leurs rappels de save

Notez que l’option :dependent est ignorée si vous avez un :has_many X, :through => Y définie.

Ainsi, dans votre exemple, vous pouvez choisir de supprimer tous les commentaires associés lors de la suppression du message, sans appeler la méthode destroy chaque commentaire. Cela ressemblerait à ceci:

 class Post < ActiveRecord::Base validates_presence_of :body, :title has_many :comments, :dependent => :delete_all end 

Mise à jour pour Rails 4:

Dans Rails 4, vous devez utiliser :destroy au lieu de :destroy_all .

Si vous utilisez :destroy_all , vous obtiendrez une exception:

L’option: dependance doit être l’une des [: destroy,: delete_all,: nullify,: ressortingct_with_error,: ressortingct_with_exception]