我正在尝试在我的架构中实现一个计数器以获取下一个问题编号。我已经将它实现为Mongoose中的一个钩子预保存钩子,一切看起来都很好......除了实际的“数字”字段没有更新。我可以很容易地告诉挂钩是通过记录到控制台的内容来解雇的,甚至该字段似乎也被分配了。但是,无论我尝试什么,“数字”字段都不会在结果中结束。
我看过几个与Mongoose钩子相关的问题,但它们似乎都与findOneAndUpdate等相关,我没有使用它。
这是我的完整型号,底部有钩子:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Project = require('./projects.js');
var IssueSchema = new Schema({
title: {type: String, required: true, trim: true, index: true},
number: {type: Number},
description: {type: String, required: true},
vote_up: {type: Number, default: 0},
vote_down: {type: Number, default: 0},
comments: [new Schema({
_id: {type: Schema.ObjectId, ref: 'users'},
description : {type: String},
likes: {type: Number},
date: {type: Date}
})],
attachments: [],
fields: [new Schema({
_id: {type: Schema.ObjectId, ref: 'fields'},
value : {type: String}
})],
project: {type: Schema.ObjectId, required: true, index: true, ref: 'projects'},
tags: {type: [Schema.ObjectId], required: false, default: ['56a2a0b1ea805d403f6d014b']},
isResolved: {type: Boolean, default: false},
created_by: {type: Schema.ObjectId, required: true, ref: 'users'},
updated_by: {type: Schema.ObjectId, required: false, ref: 'users'},
created_at: {type: Date, default: Date.now},
updated_at: {type: Date, default: Date.now}
});
IssueSchema.pre('save', function(next){
var now = new Date();
this.updated_at = now;
if(!this.created_at) {
this.created_at = now;
}
next();
})
.pre('save', function(next) {
Project.findOne({_id: this.project}).select('numberSeq').exec(function(err, doc) {
if (err) {
console.log(err);
}
console.log('pre-save hook firing');
this.number = doc.numberSeq;
console.log(this.number);
next();
});
})
.post('save', function(doc) {
Project.update({_id: doc.project}, {$inc: {numberSeq: 1}}, function(err, result) {
if (err) {
console.log(err);
}
console.log('Updated next number in seq for ' + doc.project);
});
});
module.exports = mongoose.model('issues', IssueSchema);
插入问题的途径(我猜这不是问题所在)
app.post('/api/issue/create', function(req, res) {
var issue = new Issues({
title: req.body.title,
description: req.body.description,
fields: req.body.fields,
attachments: req.body.attachments,
project: req.body.project,
created_by: req.user || req.body.created_by,
});
issue.save(function(err, result) {
if (err) {
return res.status(409).send({message: 'There was an error creating the issue: ' + err});
}
if (!result.number) {
console.log('number = :(');
}
console.log(result);
res.send({message: 'New issue created', result: result});
});
});
答案 0 :(得分:4)
您错过了this
上下文
.pre('save', function(next) {
Project.findOne({_id: this.project}).select('numberSeq').exec(function(err, doc) {
if (err) {
console.log(err);
}
console.log('pre-save hook firing');
this.number = doc.numberSeq;
console.log(this.number);
next();
});
})
你说:
this.number = doc.numberSeq;
console.log(this.number);
实际上是指findOne查询的回调函数,因此您最终会使用正确的console.log并插入错误的数据。
你可以记住预保存挂钩的这个上下文,然后在回调中使用该上下文更新数字。如下所示:
.pre('save', function(next) {
var tat=this;
Project.findOne({_id: this.project}).select('numberSeq').exec(function(err, doc) {
if (err) {
console.log(err);
}
console.log('pre-save hook firing');
tat.number = doc.numberSeq;
console.log(tat.number);
next();
});
})