Les hooks pré/post pour remove
ne sont déclenchés que lors de l'utilisation de la méthode remove()
l'instance de document, pas lorsque les méthodes du modÚle sont utilisées :
var mongoose = require("mongoose");
var db = mongoose.createConnection('mongodb://localhost/experiment');
db.once('open', function(){
testSchema = new mongoose.Schema({ title: String });
testSchema.post('remove', function(removed){
console.log('removed', removed.title);
});
var Test = db.model('Test', testSchema);
// > "removed A"
new Test({ title: 'A' }).save(function(err, created){
created.remove();
});
// Nothing :(
Test({ title: 'B' }).save(function(err, created){
Test.remove({ title: 'B' }).exec();
});
// Nothing :(
Test({ title: 'C' }).save(function(err, created){
Test.find({ title: 'C' }).remove();
});
});
cela fonctionne comme prĂ©vu. c'est la mĂȘme chose pour Model.update
. aucun middleware n'est appelé b/c middleware ne s'exécute que sur des documents mongoose qui ne sont pas impliqués lors de l'envoi d'une commande remove
directement Ă MongoDB via l'utilisation de Model.remove()
.
Je vais laisser cela ouvert pour le moment jusqu'Ă ce que je corrige les Model.remove
docs pour qu'ils soient en ligne avec Model.update
. Merci pour l'information.
Je vois. Existe-t-il un moyen de se connecter aux opérations de suppression de _all_ ?
pas actuellement.
D'accord. Merci!
eh bien tu cool si tu as patché Model.remove
mais c'est Ă toi de voir :)
Ne fonctionne pas avec findOneAndRemove
Ne semble pas non plus fonctionner lorsque vous appelez Model.remove(_id).exec();
Voici comment j'ai contourné le problÚme :
Post.findOneAndRemove({'id': data.post, 'user.uid': socket.handshake.user.id}, function(err, post) {
post.remove();
});
models.js
postSchema.post('remove', function(doc) {
console.log('removed');
});
// prints 'removed' once
Le crochet de suppression n'est pas déclenché sur findOneAndRemove, cependant, cela fonctionne lorsque j'appelle remove dans le rappel
D'accord mais pourquoi ? Je suis désolé, je n'ai pas compris pourquoi le crochet est exécuté sur Model.remove() et non sur Query.remove(). Maintenant, pourquoi devrais-je utiliser les crochets s'ils ne sont pas appelés à chaque fois ?
quel en est l'usage ?
Je veux dire : dois-je utiliser les crochets et éviter Query.remove ou ne pas utiliser les crochets et toujours supprimer manuellement ?
@Darksheep42 si vous souhaitez utiliser des crochets, utilisez doc.remove()
. La raison pour laquelle des choses comme MyModel.remove();
ne prennent pas en charge les crochets est que le document supprimé peut ne pas exister en mémoire, vous devrez donc d'abord interroger mongodb pour le document, puis dire à mongodb de le supprimer pour que les crochets fonctionnent correctement. .
Serait-il possible d'ajouter la prise en charge des crochets Query.remove()
maintenant avec le middleware de requĂȘte en 4.0Â ?
Pas pour le moment - c'est trÚs délicat car il existe déjà un middleware pour Model.remove()
Y aurait-il un problĂšme autre que le conflit de nom? Ne pourriez-vous pas simplement appeler le crochet « retirer-requĂȘte » ou quelque chose au lieu de « supprimer » ?
Ou que diriez-vous de faire ce que vous semblez faire avec update - appelez le crochet de requĂȘte mĂȘme lorsque la version doc de la fonction est utilisĂ©e. Bien sĂ»r, cela briserait la compatibilitĂ© descendante, mais c'est une idĂ©e.
Cela semble ĂȘtre une idĂ©e raisonnable, mais j'hĂ©site Ă casser l'API Ă moins qu'il n'y ait une trĂšs bonne raison de le faire. Ă l'heure actuelle, le crochet de suppression opĂšre sur un document, donc le contexte dans le middleware est le document. Pour les Query.remove()
gĂ©nĂ©raux, le document peut mĂȘme ne pas ĂȘtre en mĂ©moire. Je suppose que nous pourrions le nommer autrement comme 'remove-query , but that's nasty. What do you think about adding an extra options arg to
pre() and
post()`, quelque chose comme :
schema.pre('remove', { query: true }, function() {
// This is only attached as query middleware
});
schema.pre('remove', { doc: true }, function() {
// This will not run on Query.remove(), only doc.remove()
});
Je suppose que cela pourrait fonctionner. C'est probablement mieux que d'utiliser un nom différent et cela ne casse pas l'API. Donc je suppose que si quelqu'un l'a fait
schema.pre('remove', { query: true, doc: true }, function() {
});
Le hook serait appelĂ© Ă la fois sur les requĂȘtes de requĂȘte et de documentation. Je suppose qu'un utilisateur pourrait le faire s'il ne se souciait pas du contexte. Si vous faites cela, cependant, vous voudrez probablement aussi changer le crochet update
pour correspondre Ă ce nouveau style, et cela pourrait potentiellement casser le code des gens.
Ouais, le plus dĂ©licat dans ce contexte est "quelle est la valeur par dĂ©faut ?" Afin de prĂ©server l'API, nous devrions faire en sorte que update soit un middleware de requĂȘte par dĂ©faut, mais remove est un middleware de document par dĂ©faut. Ce sera trĂšs bizarre. Je pense que nous devrions simplement ouvrir un problĂšme sĂ©parĂ© pour 5.0 et nous en prĂ©occuper plus tard :)
Que diriez-vous, juste pour la prochaine version ou une version dans un proche avenir, nous pouvons simplement appeler le crochet « remove-query » ou quelque chose du genre ? Cela ne casse pas l'API et AFAIK devrait ĂȘtre assez facile Ă mettre en Ćuvre. Nous pourrions vraiment utiliser cette fonctionnalitĂ©, car pour le moment, vous ne pouvez pas capturer 100% des demandes de suppression via un middleware et nous prĂ©fĂ©rons de loin le faire plutĂŽt que d'appliquer certaines techniques dans notre base de code. Dans 5.0, nous pouvons le faire "de la bonne maniĂšre", mais j'aimerais juste voir cet ajout rapide avant la v5.
Approche alternative : que diriez-vous de créer une fonction preQuery()
et postQuery()
 ?
Alors au lieu d'Ă©crire
schema.pre('remove', function() {
// What is this? A doc hook? A query hook? Idk man
});
tu Ă©crirais
schema.preQuery('remove', function() {
// This is definitely a query hook
});
schema.pre('remove', function() {
// This must be a doc hook
});
Alors, pre
seraient-ils réservés aux docs ? De plus, je suppose que vous pourriez mettre cela dans une version 4.x sans casser l'API, mais nous voudrions probablement supprimer l'ancien style pre
pour le middleware de requĂȘte dans 5.0.
Oui, preQuery()
serait un bon moyen de préserver l'API jusqu'à ce que nous puissions trouver une API plus propre. J'imagine que preQuery()
pourrait ĂȘtre obsolĂšte immĂ©diatement, car je ne suis pas tout Ă fait ravi de la syntaxe.
Ce problÚme est toujours ouvert, est-il résolu ?
Qu'en est-il de la prĂ©-requĂȘte ?
Le problĂšme de la prĂ©-suppression des documents par rapport aux requĂȘtes est suivi dans #3054, pas encore implĂ©mentĂ©, les PR sont les bienvenus.
Commentaire le plus utile
Voici comment j'ai contourné le problÚme :
Le crochet de suppression n'est pas déclenché sur findOneAndRemove, cependant, cela fonctionne lorsque j'appelle remove dans le rappel