Mongoose: Retirer le crochet non déclenché lors de la suppression de documents

CrĂ©Ă© le 7 dĂ©c. 2012  Â·  24Commentaires  Â·  Source: Automattic/mongoose

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();
  });

});
docs

Commentaire le plus utile

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

Tous les 24 commentaires

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.

Cette page vous a été utile?
0 / 5 - 0 notes