【问题标题】:node / mongoose: getting to request-context in mongoose middleware节点/猫鼬:在猫鼬中间件中获取请求上下文
【发布时间】:2020-11-02 15:46:13
【问题描述】:

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

【问题讨论】:

    标签: node.js mongoose


    【解决方案1】:

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

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

    【讨论】:

    • 我应该补充一点,我在嵌入式架构上定义pre,而我在“嵌入式​​父级”上调用 save 。您的解决方案适用于普通文档,但不适用于我描述的嵌入式案例。我已经更新了我的问题以反映这一点,现在我知道这很重要。无论如何都向上,因为它回答了我不完整的问题
    • @Bill 是否有可能以某种方式将对象/变量传递给pre validate 中间件,而不仅仅是pre save 中间件?用例是根据当前用户的首选项传递字段的默认值(当前用户和首选项附加到我的快速路由中的req 对象)。我需要在验证之前传递它们,因为应该验证这些值(即使它们是默认值)(还有一些复杂的验证:一个字段依赖于另一个字段,等等)。
    • 您好,我可以在middlewar pre save中访问req,但是文档没有成功保存。它返回未定义的const savedItem = await item.save(req, function() {});。没有错误。回调里面应该是什么?
    【解决方案2】:

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

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

    谢谢,

    【讨论】:

    • 保存方法呢?
    【解决方案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()
    })
    

    【讨论】:

    • 它适用于保存但上下文在更新时丢失:'(
    猜你喜欢
    • 1970-01-01
    • 2012-10-21
    • 1970-01-01
    • 2017-05-31
    • 2019-10-26
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 2020-04-15
    相关资源
    最近更新 更多