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处理的,所以不能保证一个请求会在另一个请求开始之前完成。 所以这样的情况很容易发生:
- 请求A进来。
- Sails获取请求A的会话并将其存储在全局
$_SESSION
对象中。 - 请求调用
SomeModel.find()
,asynchronous调用数据库 - 虽然数据库发挥了神奇的作用,但Request A放弃了对Node线程的控制
- 请求B进来。
- Sails获取请求B的会话并将其存储在全局
$_SESSION
对象中。 - 请求B放弃对线程的控制来做其他一些asynchronous调用。
- 请求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, '/'); };