6

我正在使用 mongoose(在节点上),我正在尝试使用 Mongoose 中间件在保存时向模型添加一些额外的字段。

我正在考虑想要添加 lastmodifiedsince-date 的常用案例。但是,我还想自动添加已完成保存的用户的名称/个人资料链接。

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-request。

谢谢

编辑

pre在嵌入式模式上定义,而我正在调用save嵌入式实例的父级。下面发布的解决方案(将 arg 作为保存的第一个参数传递)适用于非嵌入式案例,但不适用于我的案例。

4

3 回答 3

12

您可以将数据传递给您的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();
})

如果你真的需要这个功能,我建议你重新打开我上面链接的问题。

于 2012-05-07T16:57:32.500 回答
3

我知道这确实是个老问题,但我花了半天时间试图解决这个问题,所以我正在回答这个问题。我们可以将额外的属性作为选项传递,如下例所示 -

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

谢谢,

于 2017-03-13T16:13:46.297 回答
3

它可以通过“请求上下文”来完成。步骤:

安装请求上下文

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()
})
于 2018-11-30T03:14:29.957 回答