2015-08-15 6 views
0

Я бы не удалял удаление любого дополнительного документа, поэтому я добавил ошибку в промежуточное ПО pre ('remove') каждой схемы дополнительного документа.Предварительно удалите промежуточное программное обеспечение Mongoose

При вызове функции .remove() он эффективно вызывает промежуточное программное обеспечение. Но когда он удаляется без вызова remove(), промежуточное программное обеспечение не проверяет, было ли оно удалено.

Случаи, когда дело касается того, когда я получаю объект из удаленного источника, я хотел бы выполнить все проверки целостности через посреднические посредники, чтобы сохранить все в одном месте. Удаленный источник может по ошибке или не удалять один из вспомогательных документов. Поэтому, когда Mongoose проверяет весь документ, суб-документ уже удален, не вызывая функцию .remove().

Вот минимальный рабочий пример моей проблемы:

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

var subDateSchema = new Schema({ 
    date_add: {type: Date, default: Date.now}, 
    date_remove: {type: Date, default: null} 
}); 

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

subDateSchema.pre('remove', function(next){ 
    next(new Error("YOU CAN'T DELETE ANY ACTIVATION DATE")); 
}); 

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); 
    /** 
     * Here I tried 
     * newresource.markModified('activation_dates'); 
     * On update it *DOES* trigger pre save and pre validate 
     * But it does nothing to deleted content 
    **/ 
    newresource.save(function(err){ 
     if(err) throw err; 
    }); 
}); 

Так что мой вопрос: Есть ли чистый способ вызова подменю док удаления промежуточного программного не прибегая для проверки всех предыдущих элементов и сравнить с какие из них удаляются?

+0

«Поддокументы» и, следовательно, «члены массивов» ** никогда не «удаляются», как предполагает подсказка. Они только «вытягиваются» из массива. Вот почему ваш код не работает. –

+0

@BlakesSeven в порядке, так есть ли способ проверить, что вспомогательные документы вытягиваются из массива? – Musinux

+0

Подумайте об этом, я на самом деле не думаю, что модели мангуста поддерживают это вообще. Возможность даже «поддерживать» процесс «проверки» на «атомарных» операциях, таких как '$ pull' в' .update() 'или подобном, также является относительно« новой »вещью в кодовой базе. Поэтому я бы рекомендовал, чтобы более подходящим было использование «проверки правильности», а не промежуточного программного обеспечения .pre(). Не пробовал сам процесс. Можете попробовать в выходные дни. –

ответ

1

После немногих исследований, я нашел это:

Обходной может быть зацепить событие для всего массива документов Sub и иметь копию предыдущего массива данных.

Это полный рабочий пример того, как быть уверенным, что элемент массива не был удален или вытащен. Чтобы проверить изменения, вам понадобятся дополнительные изменения.

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

К сожалению, я не смог найти другого решения, кроме того, чтобы выполнять цикл над всеми элементами и извлекать исходный документ.

Смежные вопросы