Réponses:
Exécute essentiellement destroy
tous les rappels sur le modèle alors delete
qu'il ne le fait pas.
Depuis l' API Rails :
ActiveRecord::Persistence.delete
Supprime l'enregistrement dans la base de données et fige cette instance pour indiquer qu'aucune modification ne doit être apportée (car elles ne peuvent pas être persistées). Renvoie l'instance gelée.
La ligne est simplement supprimée avec une instruction SQL DELETE sur la clé primaire de l'enregistrement et aucun rappel n'est exécuté.
Pour appliquer les rappels before_destroy et after_destroy de l'objet ou toute option d'association dépendante, utilisez #destroy.
ActiveRecord::Persistence.destroy
Supprime l'enregistrement dans la base de données et fige cette instance pour indiquer qu'aucune modification ne doit être apportée (car elles ne peuvent pas être persistées).
Il y a une série de rappels associés à destroy. Si le rappel before_destroy renvoie false, l'action est annulée et destroy renvoie false. Voir ActiveRecord :: Callbacks pour plus de détails.
model#before_destroy
qui peut être utilisé pour interrompre l' destroy()
appel final sous certaines conditions.
delete
supprimera uniquement l'enregistrement d'objet actuel de la base de données, mais pas les enregistrements enfants associés de la base de données.
destroy
supprimera l'enregistrement d'objet actuel de db et également son enregistrement enfant associé de db.
Leur utilisation compte vraiment:
Si vos objets parents multiples partagent des objets enfants communs, l'appel destroy
à un objet parent spécifique supprimera les objets enfants qui sont partagés entre d'autres parents multiples.
destroy
est descendant , pas enfant : selon la documentation, destroy "crée un nouvel objet à partir des attributs, puis appelle destroy dessus". rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FRelation:destroy
Lorsque vous invoquez destroy
ou destroy_all
sur un ActiveRecord
objet, le ActiveRecord
processus de `` destruction '' est lancé, il analyse la classe que vous supprimez, il détermine ce qu'il doit faire pour les dépendances, exécute les validations, etc.
Lorsque vous appelez delete
ou delete_all
sur un objet, ActiveRecord
essaie simplement d'exécuter la DELETE FROM tablename WHERE conditions
requête sur la base de données, sans effectuer d'autres ActiveRecord
tâches de niveau.
Oui, il existe une différence majeure entre les deux méthodes Utilisez delete_all si vous souhaitez que les enregistrements soient supprimés rapidement sans que les rappels de modèle soient appelés
Si vous vous souciez des rappels de vos modèles, utilisez destroy_all
Des documents officiels
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
destroy_all (conditions = nil) public
Détruit les conditions de correspondance des enregistrements en instanciant chaque enregistrement et en appelant sa méthode destroy. Les rappels de chaque objet sont exécutés (y compris: les options d'association dépendantes et les méthodes Observer before_destroy / after_destroy). Renvoie la collection d'objets qui ont été détruits; chacun sera gelé, pour refléter qu'aucune modification ne devrait être apportée (puisqu'ils ne peuvent pas être persistés).
Remarque: L'instanciation, l'exécution de rappel et la suppression de chaque enregistrement peuvent prendre du temps lorsque vous supprimez plusieurs enregistrements à la fois. Il génère au moins une requête SQL DELETE par enregistrement (ou éventuellement plus, pour appliquer vos rappels). Si vous souhaitez supprimer rapidement de nombreuses lignes, sans vous soucier de leurs associations ou rappels, utilisez plutôt delete_all.
Fondamentalement, «supprimer» envoie une requête directement à la base de données pour supprimer l'enregistrement. Dans ce cas, Rails ne sait pas quels attributs sont dans l'enregistrement qu'il supprime ni s'il y a des rappels (tels que before_destroy
).
La méthode "destroy" prend l'ID transmis, récupère le modèle de la base de données en utilisant la méthode "find", puis appelle destroy à ce sujet. Cela signifie que les rappels sont déclenchés.
Vous voudrez utiliser "supprimer" si vous ne voulez pas que les rappels soient déclenchés ou si vous voulez de meilleures performances. Sinon (et la plupart du temps) vous voudrez utiliser "destroy".
Beaucoup de réponses déjà; voulait sauter avec un peu plus.
Pour has_many, destroy et destroy_all appellent toujours la méthode destroy des enregistrements supprimés afin que les rappels soient exécutés. Cependant, delete et delete_all effectueront la suppression conformément à la stratégie spécifiée par l'option: dependante, ou si aucune option: dependante n'est donnée, elle suivra la stratégie par défaut. La stratégie par défaut est de ne rien faire (laisser les clés étrangères avec les ID parents définis), sauf pour has_many: through, où la stratégie par défaut est delete_all (supprimer les enregistrements de jointure, sans exécuter leurs rappels).
Le delete
verbage fonctionne différemment pour ActiveRecord::Association.has_many
et ActiveRecord::Base
. Pour ce dernier, delete exécutera SQL DELETE
et contournera toutes les validations / rappels. Le premier sera exécuté en fonction de l' :dependent
option transmise à l'association. Cependant, lors des tests, j'ai trouvé l'effet secondaire suivant où les rappels n'étaient exécutés que pour delete
et nondelete_all
dependent: :destroy
Exemple:
class Parent < ApplicationRecord
has_many :children,
before_remove: -> (_) { puts "before_remove callback" },
dependent: :destroy
end
class Child < ApplicationRecord
belongs_to :parent
before_destroy -> { puts "before_destroy callback" }
end
> child.delete # Ran without callbacks
Child Destroy (99.6ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 21]]
> parent.children.delete(other_child) # Ran with callbacks
before_remove callback
before_destroy callback
Child Destroy (0.4ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 22]]
> parent.children.delete_all # Ran without callbacks
Child Destroy (1.0ms) DELETE FROM "children" WHERE "children"."parent_id" = $1 [["parent_id", 1]]