【发布时间】:2015-11-08 14:43:40
【问题描述】:
我会阻止任何子文档被删除,因此我在每个子文档架构的 pre('remove') 中间件中添加了一个错误。
当调用 .remove() 函数时,它实际上调用了中间件。但是当它被删除而不调用remove()时,中间件不会检查它是否已经被删除。
重要的情况是当我从远程源接收对象时,我想通过 mongoose 中间件执行所有完整性检查,以将所有内容保持在同一个位置。无论是否错误,远程源都可能删除了其中一个子文档。所以当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;
});
});
所以我的问题是:有没有一种干净的方法来调用子文档删除中间件,而无需继续检查所有以前的元素并与新元素进行比较以查看哪些元素被删除?
【问题讨论】:
-
“子文档”,因此“数组成员”从不按照动作钩子的建议“删除”。它们只会从阵列中“拉出”。这就是您的代码失败的原因。
-
@BlakesSeven 好吧,有没有办法检查从数组中提取的子文档?
-
仔细想想,其实我觉得猫鼬模型根本不支持这个。甚至在
.update()或类似的“原子”操作(例如$pull)上“支持”“验证”过程的能力在代码库中也是一个非常“新”的东西。因此,我建议“验证”挂钩而不是.pre()中间件更合适。我自己还没有尝试过你的过程。周末可以试试。
标签: node.js mongodb mongoose subdocument