MEAN 2多租户(多个集合保存相互引用)

时间:2017-08-27 18:55:03

标签: node.js express mongoose multi-tenant async.js

因此,在学习JS,特别是MEAN 2堆栈的同时,我试图建立一个基本的多租户应用程序。我在快递中建立了注册路线,而我想要实现的流程将是:

注册公司名称,电子邮件和密码。该信息将用于保存新租户,然后返回新租户的_id,然后使用此新ID,电子邮件和密码来保存新用户。

最接近的是:

router.post('/', function (req, res, next) {

  var tenant = new Tenant({
    name: req.body.name
  });
  var newTenant;

  tenant.save(function (err, tenant) {
    if (err) {
      return res.status(500).json({
        title: 'An error has occured',
        error: err
      });
    }
    res.status(201).json({
      message: 'Tenant created',
      obj: tenant
    });
    return(tenant._id);
    newTenant = tenant;
  });

  Tenant.findById(newTenant._id, function(err, tenant) {
    if (err) {
      return res.status(500).json({
        title:'An error occured',
        error: err
      });
    }
    var user = new User({
      email: req.body.email,
      password: bcrypt.hashSync(req.body.password, 10),
      active: req.body.active,
      tenant: tenant
    });
    user.save(function (err, user) {
      if (err) {
        return res.status(500).json({
          title: 'An error has occured',
          error: err
        });
      }
      res.status(201).json({
        message: 'User created',
        obj: user
      });
    });
  });

});

module.exports = router;

我收到错误:无法在发送标题后设置标题。 我想我知道我错在哪里,返回租户信息。我认为Async是答案,但无法弄清楚如何实现它。很抱歉,如果这是一个愚蠢的问题,或者我错过了一些明显的问题,我对此非常陌生,并且回调正在努力。

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为res.status()会在触发后立即设置标头。您在检查错误时尝试多次执行此操作,然后尝试在Tenant.findById()中再次设置状态代码。

你最终得到的结果如下:

if (err) set headers
set headers (again)
findById()
if (err) set headers
set headers (again)

在写出你的回复时你必须要小心,你只能在逻辑流程的最后一点做到这一点。您还可以设置全局错误处理程序和throw new Error()并停止逻辑流立即处理输出。如果不这样做,即使遇到错误,您的代码也会继续执行。

另一个提示:回调不适用于退货。虽然你可以安排它们工作,或者实现一个promise架构,但最简单的修复(也是最容易学习的)是使你的函数都异步。

尝试改为:

tenant.save(function (err, tenant, callback) {
  // add a callback param to your fn ^
  if (err) {
    throw({
      code: 500,
      title: 'An error has occured',
      error: err
    });
  } else {
  // ^ add an else statement so you don't set the headers twice 
  // (because res.status() sets headers)
    res.status(201).json({
      message: 'Tenant created',
      obj: tenant
    });
  }
  callback(err, tenant);
  // call your async function instead of return, 
  // and pass both err and tenant as params
  // (one or the other may be undefined though, if it fails/succeeds)
});

...为其余任务创建额外的隔离功能(甚至模块),然后您可以像这样调用您的函数:

tenant.save(function(err, tenant) {
  Tenant.findById(tenant._id, function(err, tenant) {
    var user = new User({...})
    user.save()
  });
});