node / mongoose:在mongoose中间件中获取请求上下文

时间:2012-05-07 16:04:33

标签: node.js mongoose

我正在使用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作为保存的第一个参数传递)适用于非嵌入式案例,但不适用于我的案例。

3 个答案:

答案 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()
})