我正在使用mongoose(在节点上),我正在尝试使用Mongoose中间件向模型添加一些额外的字段。
我正在考虑经常使用的案例,想要添加lastmodifiedsince-date。 但是,我还想自动添加已完成保存的用户的名称/ profilelink。
schema.pre('save', function (next) {
this.lasteditby=req.user.name; //how to get to 'req'?
this.lasteditdate = new Date();
next()
})
我正在使用护照 - http://passportjs.org/ - 导致req.user存在,req
当然是http请求。
由于
修改
我在嵌入式架构上定义了pre
,而我在嵌入式实例的父级上调用了save
。下面发布的解决方案(将arg作为保存的第一个参数传递)适用于非嵌入式案例,但不适用于我的案例。
答案 0 :(得分:9)
您可以将数据传递到Model.save()
来电,然后将其传递到您的中间件。
// in your route/controller
var item = new Item();
item.save(req, function() { /*a callback is required when passing args*/ });
// in your model
item.pre('save', function (next, req, callback) {
console.log(req);
next(callback);
});
不幸的是,这对今天的嵌入式架构不起作用(参见https://github.com/LearnBoost/mongoose/issues/838)。一种解决方法是将属性附加到父级,然后在嵌入式文档中访问它:
a = new newModel;
a._saveArg = 'hack';
embedded.pre('save', function (next) {
console.log(this.parent._saveArg);
next();
})
如果您确实需要此功能,我建议您重新打开我上面链接的问题。
答案 1 :(得分:1)
我知道这是一个很老的问题,但我正在回答这个问题,因为我花了半天的时间试图解决这个问题。我们可以将额外的属性作为选项传递,如下例所示 -
findOneAndUpdate({ '_id': id }, model, { **upsert: true, new: true, customUserId: userId, ipAddress: ipaddress.clientIp** }, function (err, objPersonnel) {
在预更新和保存访问中如下 -
schema.pre('findOneAndUpdate', function (next) {
// this.options.customUserId,
// this.options.ipAddress
});
谢谢,
答案 2 :(得分:0)
这可以通过'request-context'完成。步骤:
安装请求上下文
npm i request-context --save
在您的应用/服务器初始化文件中:
var express = require('express'),
app = express();
//You awesome code ...
const contextService = require('request-context');
app.use(contextService.middleware('request'));
//Add the middleware
app.all('*', function(req, res, next) {
contextService.set('request.req', req);
next();
})
在您的猫鼬模型中:
const contextService = require('request-context');
//Your model define
schema.pre('save', function (next) {
req = contextService.get('request.req');
// your awesome code
next()
})