首页 > 解决方案 > 在 pre 'save' 和 pre 'findOneAndUpdate' 钩子中的 Mongoose 插件更改不会被持久化

问题描述

我有一个使用 Mongoose 库连接到 MongoDB 的 node-express 应用程序。但是我无法让我的自定义 Mongoose 插件在将文档保存到数据库之前对其进行更改。这是我定义插件的方式:

const requestContext = require('request-context');

module.exports = (schema, options) => {
    schema.pre('save', next => {
        const author = requestContext.get('request').author;
        this._createdBy = author.sub;
        this._owner = author.sub;
        this._groupOwner = author.group;
        next();
    });
    schema.pre('findOneAndUpdate', next => {
        const author = requestContext.get('request').author;
        this._lastEditAt = Date.now();
        this._lastEditBy = author.sub;
        next();
    });
}

然后我将它添加到这样的架构中:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const trace = require('../plugins/trace');

const PostSchema = new Schema({
    title: String,
    Text: String,
    category: String,
    _createdAt: {
        type: Date,
        default: Date.now
    },
    _lastEditAt: Date,
    _createdBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    _lastEditBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    _owner: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },_groupOwner: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Group'
    }
});

PostSchema.plugin(trace);
exports.schema = PostSchema;
exports.model = mongoose.model('Post', PostSchema);

在我的 Express 控制器中:

const router = require('express').Router();

const Post = require('../model/post').model;

router.post('/', (req, res) => {
    const post = new Post(req.body);
    post.save()
        .then(() => res.json(post))
        .catch(err => res.status(400).json(err));
});

router.put('/', (req, res) => {
    Post.findByIdAndUpdate(req.body._id, req.body, {new: true})
        .then(post => res.json(post))
        .catch(err => res.status(400).json(err));
});

插件定义的预挂钩被触发,但它们带来的更改永远不会持久化到数据库中。这是猫鼬插件系统中的错误吗?我试过了Mongoose@4.13.9Mongoose@5.3.3但没有一个有效。

标签: node.jsmongodbmongoose

解决方案


我整个周末都在为这个问题苦苦挣扎。幸运的是,我找到了问题的根源。首先:我在我的钩子方法中使用了箭头函数,它改变了this关键字的上下文。所以我必须使用旧的 es5 函数语法来定义我的钩子函数,如下所示:

const requestContext = require('request-context');

module.exports = (schema, options) => {
    schema.pre('save', function(next) {
        const author = requestContext.get('request').author;
        this._createdBy = author.sub;
        this._owner = author.sub;
        this._groupOwner = author.group;
        next();
    });
}

推荐阅读