【问题标题】:How to access request object in sails.js lifecycle callbacks?如何在sails.js 生命周期回调中访问请求对象?
【发布时间】:2015-02-06 16:36:31
【问题描述】:

假设我有这个模型:

module.exports = {

  attributes: {

    title: {
      type: 'string',
      required: true
    },

    content: {
      type: 'string',
      required: true
    },

    createdBy: {
      type: 'string',
      required: true
    }
  }
}

我需要将当前用户 ID 设置为模型的 createdBy 属性。我认为我可以使用 beforeValidate 生命周期回调来做到这一点,但我无法访问存储当前用户的请求对象。有没有办法访问它,还是我应该以其他方式解决这个问题?

我试过这个没有成功:

beforeValidate: function (values, next) {
  var req = this.req; // this is undefined
  values.createdBy = req.user.id;
  next();
}

【问题讨论】:

    标签: sails.js waterline


    【解决方案1】:

    由于请求超出了 ORM 的范围,我猜我的方法是错误的,我需要将 createdBy 数据添加到中间件中的 req.body 中。但由于不是对每个请求都这样做,我猜最好通过策略来做到这一点。像这样:

    PostController: {
    
      '*': ['passport', 'sessionAuth'],
    
      create: ['passport', 'sessionAuth',
        function (req, res, next) {
          if (typeof req.body.createdBy === 'undefined') {
            req.body.createdBy = req.user.id;
          }
          next();
        }
      ]
    }
    

    这样我就不需要覆盖蓝图了。

    【讨论】:

    • 我很惊讶越来越多的人不推荐这个。始终将其添加到控制器中是蓝图目标的反模式。政策让这一切变得容易得多。
    • 好的,但是由于这个策略,我如何能够在生命周期回调中访问 req?
    • @AdamPietrasiak 这并没有解决这个问题,而是这个“解决方案”建议使用中间件来实现我最初想要做的事情。请参阅 Matt Lo 的评论。
    【解决方案2】:

    你可以通过两种方式做到这一点。

    首先是在控制器中添加该数据。类似的东西

    // /api/controllers/mycontroller.js
    module.exports = {
        new: function(req, res) {
            if (typeof req.user.id !== 'undefined') {
                req.body.createdBy = req.user.id;     // req.body or req.params
            }
            MyModel.create(req.body /* ... */)
        }
    }
    

    如果您使用MyModel 进行大量数据操作,那可能会很烦人。因此,您可以将静态方法添加到模型中以使用用户 ID 保存它。比如:

    // /api/models/myModel.js
    module.exports = {
        attributes: {/* ... */},
    
        createFromRequest: function(req, cb) {
            // do anything you want with your request
            // for example add user id to req.body
            if (typeof req.user.id !== 'undefined') {
                req.body.createdBy = req.user.id;
            }
            MyModel.create(req.body, cb);
        }
    }
    

    然后在你的控制器中使用它

    // /api/controllers/mycontroller.js
    module.exports = {
        new: function(req, res) {
            MyModel.createFromRequest(req, function(err, data) {
                res.send(data);
            });
        }
    }
    

    【讨论】:

    • 谢谢格伦!我试图避免覆盖蓝图操作。但我不知道如果最好。看看我自己的回答,有意义吗?
    • @MartinSchaer,我不会将它用于实际项目。第一个原因,以这种方式使用策略并不明显。我的意思是,如果我有项目并且知道某个用户 ID 在保存之前添加到请求正文中,那么策略是我尝试找到它的最后一个地方。第二个原因是很难重用这段代码。如果您想将用户 ID 添加到模型的其他方法,您应该再次编写此函数(或创建单个策略以添加用户 ID)。这是我的观点,但我认为策略应该用于访问操作,模型应该用于数据操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多