MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Sous-document Mongoose avant suppression du middleware non appelé

Après quelques recherches, j'ai trouvé ceci :

Une solution de contournement peut être de raccorder un événement à l'ensemble du tableau de sous-documents et d'avoir une copie du tableau de données précédent.

Ceci est un exemple de travail complet sur la façon de s'assurer qu'un élément de tableau n'a pas été supprimé ou extrait . Pour vérifier les modifications, vous aurez besoin d'autres modifications.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var ResourceSchema = new Schema({
    activation_dates: [subDateSchema]
});

// This virtual permits to store the original array accross the middlewares
ResourceSchema.virtual("original").set(function(item){
    this._original = item;
}).get(function(){
    return this._original;
});

// This middleware checks for a previous version of the "Resource"
ResourceSchema.pre("validate", function(next){
    var self = this;
    mongoose.model("Resource").findById(this._id, function(err, doc){
        if(err) throw err;
        self.original = doc;
        next();
    });
});

// This validation block checks for any modification of the array of sub documents
ResourceSchema.path("activation_dates").validate(function(value){
    var j;
    if(this.original){
        // if the new array is smaller than the original, no need to go further
        if(this.original.activation_dates.length > value.length){
            return false;
        }

        for(var i=0; i < this.original.activation_dates.length; i++){
            j=0;
            // if the array element has been deleted but not pulled out, we need to check it
            if(typeof value[j] == "undefined" || typeof value[j]._id == "undefined"){
                return false;
            }

            while(value.length > j && this.original.activation_dates[i]._id.toString() != value[j]._id.toString()){
                j++;
            }
            if(j == value.length){
                return false;
            }
        }
    }
    return true;
}, "You deleted at least one element of the array");

var Resource = mongoose.model('Resource', ResourceSchema);

var newresource = new Resource({
    activation_dates: [{
        date_add: Date.now()
    }]
});

newresource.save(function(err){
    if(err) throw err;

    newresource.activation_dates.splice(0, 1);
    // OR:
    //delete newresource.activation_dates[0];
    // this line is essential in the case you *delete* but not pull out
    newresource.markModified('activation_dates');

    newresource.save(function(err){
        if(err) throw err;
    });
});

Malheureusement, je n'ai pas trouvé d'autre solution que de faire une boucle sur tous les éléments et de récupérer le document d'origine.