猫鼬的Pre-Save Hook正在触发,但未保存其他字段(不使用model.update) [英] Mongoose Pre-Save Hook is Firing, but Not Saving Additional Field (NOT using model.update)

查看:57
本文介绍了猫鼬的Pre-Save Hook正在触发,但未保存其他字段(不使用model.update)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的架构中实现一个计数器以获取下一个发行号.我已经在Mongoose中将其实现为钩子保存前的钩子,并且一切看起来都很好……除了实际的"number"字段没有更新.我可以很容易地告诉钩子是由登录到控制台的内容触发的,即使该字段似乎已被分配.但是,无论如何,"number"字段都不会出现在结果中.

I am attempting to implement a counter in my schema to grab the next issue number. I have implemented it as a hook pre-save hook in Mongoose, and everything looks fine... with the exception the actual 'number' field does not update. I can easily tell the hook is firing off by what gets logged to the console, even the field seems to get assigned. But alas, no matter what I try, the 'number' field does not end up in the results.

我已经看到了一些与猫鼬挂钩相关的问题,但是它们似乎都与我未使用过的findOneAndUpdate之类有关.

I have seen a couple issues related to Mongoose hooks, but they all seem to be related to findOneAndUpdate or the like, which I am not using.

这是我的完整模型,底部带有挂钩:

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

插入问题的途径(我想这不是问题所在)

And the route to insert the issue (I am guessing this isn't where the issue is)

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

推荐答案

您在这里的this上下文中错过了机会,

You are missing out on the this context here,

.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和错误的数据.

actually refers to the callback function of the findOne query, thus you are ending up with the right console.log and wrong data inserted.

您可以记住pre save钩子的上下文,然后在回调中使用该上下文更新编号.如下所示:

you can remember this context of the pre save hook, and later update the number using that context inside the callback. like below:

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

这篇关于猫鼬的Pre-Save Hook正在触发,但未保存其他字段(不使用model.update)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆