sails.js在模型中使用会话参数

这是这个问题的延伸。

在我的模型中,每个人都需要在创build时设置一个companyId,并且每个人都需要通过同一个session持有的companyid过滤模型。

有了sails.js ,我已经阅读并理解,除非使用控制器注入会话,否则会话在模型中不可用,但是这需要我用非常重复的代码来编写所有控制器/操作。 不幸的。

我喜欢sails.js并想要切换,但任何人都可以向我描述一个更好的方法? 我希望我错过了一些东西。

所以,如果我正确地理解了你,你想在你的控制器中避免这样的代码:

SomeModel.create({companyId: req.session.companyId, ...}) SomeModel.find({companyId: req.session.companyId, ...}) 

很公平。 也许你担心companyId将来会被重命名,或者需要进一步处理。 如果您使用自定义控制器操作,最简单的解决scheme是将接受请求的模型的类方法作为参数:

 SomeModel.doCreate(req, ...); SomeModel.doFind(req, ...); 

另一方面,如果你使用的是v0.10.x,你可以使用蓝图来进行一些CRUD操作,那么你就可以使用你自己的代码覆盖蓝图 ,这样你的所有创build和查找就会自动使用该companyId来自会议。

如果你来自非节点的背景,这可能会引起一些头疼的事情。 “为什么不能让这个会议到处都可以?” 你可能会问。 “像他们用PHP做的!”

原因是PHP是无状态的 –每一个进来的请求基本上都是应用程序的全新副本,在请求之间没有任何内存被共享。 这意味着任何全局variables只对一个请求有效。 那个美好的$_SESSION散列是你自己和你的,一旦请求被处理,它就消失了。

将其与Node应用程序进行对比,Node应用程序本质上是在单个进程中运行 您设置的任何全局variables都将在每个进入的请求之间共享,而且由于请求是asynchronous处理的,所以不能保证一个请求会在另一个请求开始之前完成。 所以这样的情况很容易发生:

  1. 请求A进来。
  2. Sails获取请求A的会话并将其存储在全局$_SESSION对象中。
  3. 请求调用SomeModel.find() ,asynchronous调用数据库
  4. 虽然数据库发挥了神奇的作用,但Request A放弃了对Node线程的控制
  5. 请求B进来。
  6. Sails获取请求B的会话并将其存储在全局$_SESSION对象中。
  7. 请求B放弃对线程的控制来做其他一些asynchronous调用。
  8. 请求A返回其数据库调用的结果,并从$_SESSION对象读取一些内容。

您可以在这里看到问题 – 请求A现在有错误的会话数据。 这就是会话对象存在于请求对象中的原因,以及为什么需要传递给任何想要使用它的代码。 试图绕开这一难题将不可避免地导致麻烦。

我能想到的最好的select是利用JS,并使一些全球可访问的function。

但它会有一个代码气味:(

我更喜欢在body.param中添加companyId这样的策略:

  // Needs to be Logged module.exports = function(req, res, next) { sails.log.verbose('[Policy.insertCompanyId() called] ' + __filename); if (req.session) { req.body.user = req.session.companyId; //or something like AuthService.getCompanyId(req.session); return next(); } var err = 'Missing companyId'; //log ... return res.redirect(307, '/'); };