Rails: dépendant =>: détruit VS: dépendant =>: delete_all


192

Dans les guides de rails, il est décrit comme ceci:

Les objets seront en outre détruits s'ils sont associés à :dependent => :destroy, et supprimés s'ils sont associés à:dependent => :delete_all

Bien, cool. Mais quelle est la différence entre être détruit et supprimé? J'ai essayé les deux et il semble faire la même chose.

Réponses:


200

La différence est avec le rappel.

Le :delete_allse fait directement dans votre application et supprime par SQL:

DELETE * FROM users where compagny_id = XXXX

Avec le :destroy, il y a une instanciation de tous vos enfants. Donc, si vous ne pouvez pas le détruire ou si chacun a le sien :dependent, ses rappels peuvent être appelés.


83
L'instanciation et l'appel de destroy sur chacun des objets enfants seront lents si vous avez beaucoup d'enfants (et n ^ 2 si vous avez des petits-enfants, et ainsi de suite). delete_all est le genre de solution "nuke it from orbit" où vous ne vous souciez pas / n'avez pas de callback avant / après destroy sur les modèles.
Ryan Bigg

131

Sur une association de modèle Rails, vous pouvez spécifier l' :dependentoption, qui peut prendre l'une des trois formes suivantes:

  • :destroy/:destroy_allLes objets associés sont détruits à côté de cet objet en appelant leur destroyméthode
  • :delete/:delete_allTous les objets associés sont détruits immédiatement sans appeler leur :destroyméthode
  • :nullifyToutes les clés étrangères des objets associés sont définies sur NULLsans appeler leurs saverappels

2
Voir api.rubyonrails.org/classes/ActiveRecord/Associations/… (recherchez "nullify") pour les rdocs faisant autorité.
mrm

21
Depuis Rails 3.0, il est également possible de spécifier :restrict. S'il est défini sur: restreindre, cet objet ne peut pas être supprimé s'il a un objet associé.
RocketR

17
il n'y a pas :deleteou des :destroy_alloptions par son apparence? L'option: dépendante attend soit: destroy,: delete_all,: nullify ou: restrict (: delete)
Mike Campbell

2
@MikeCampbell, :deleteet les :destroy_alloptions n'existent pas. Cependant, il existe des méthodes de classe sur les modèles qui sont appelées deleteet destroy_allcela pourrait donc être la raison de la confusion.
berezovskyi le

@MikeCampbell Il vous manque quelques options supplémentaires, Voir L'option: dépendante doit être l'une des [: destroy,: delete_all,: nullify,: restrict_with_error,: restrict_with_exception]
Pravin Mishra

30

See destroy supprime ses éléments associésdelete_all peut supprimer plusieurs données de la table self commeDELETE * FROM table where field = 'xyz'

: Options possibles dépendantes:

Contrôle ce qui arrive aux objets associés lorsque leur propriétaire est détruit. Notez que ceux-ci sont implémentés en tant que rappels, et Rails exécute les rappels dans l'ordre. Par conséquent, d'autres rappels similaires peuvent affecter le comportement: dépendant et le :dependentcomportement peut affecter d'autres rappels.

:destroy provoque la destruction de tous les objets associés.

:delete_all provoque la suppression directe de tous les objets associés de la base de données (les callbacks ne seront donc pas exécutés).

:nullifyprovoque la mise à NULL des clés étrangères. Les rappels ne sont pas exécutés.

:restrict_with_exception provoque la levée d'une exception s'il existe des enregistrements associés.

:restrict_with_error provoque l'ajout d'une erreur au propriétaire s'il existe des objets associés.

Si vous utilisez cette :throughoption, l'association sur le modèle de jointure doit être une appartenance à, et les enregistrements qui sont supprimés sont les enregistrements de jointure, plutôt que les enregistrements associés.


3

En fait, la principale différence est que les rappels ne seront pas appelés lorsqu'ils ont :delete_allété utilisés. Mais lorsqu'elle est utilisée, :destroyla pile de rappels ( :after_destroy, :after_commit...) sera déclenchée.

Par conséquent, si vous avez des touch:déclarations dans les modèles en cours de suppression, il est préférable d'utiliser dependent: :delete_allplutôt «depend:: destroy».

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.