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

时间:2014-04-04 03:50:21

标签: node.js sails.js

这是this question的扩展名。

在我的模型中,每个人都需要在创建时设置companyId,并且每个人都需要通过同一个会话持有的公司来过滤模型。

使用sails.js,我已经阅读并理解模型中没有会话,除非我使用控制器注入它,但是这需要我用非常非常重复的东西编写所有控制器/动作。不幸的。

我喜欢sails.js并希望进行切换,但是有人可以向我描述更好的方法吗?我希望我错过了一些东西。

3 个答案:

答案 0 :(得分:12)

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

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

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

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

另一方面,如果您使用v0.10.x并且可以使用蓝图进行某些CRUD操作,那么您将受益于override the blueprints with your own code的功能,以便您创建所有发现会自动使用会话中的companyId

如果您来自非节点背景,这可能会引起一些头疼。 "为什么你不能在任何地方提供会话?"你可能会问。 "就像他们用PHP做的那样!"

原因是PHP是无状态 - 每个进来的请求基本上都是应用程序的新副本,请求之间没有任何内存共享。这意味着任何全局变量仅在单个请求的生命周期内有效。那个精彩的$_SESSION哈希是你自己和你的哈希,一旦请求被处理,它就会消失。

将此与Node应用程序进行对比,Node应用程序基本上在单个进程中运行。您设置的任何全局变量将在每个进入的请求之间共享,并且由于请求是异步处理的,因此无法保证一个请求在另一个请求启动之前完成。所以这样的场景很容易发生:

  1. 请求A进来。
  2. Sails获取请求A的会话并将其存储在全局$_SESSION对象中。
  3. 请求A调用SomeModel.find(),它以异步方式调用数据库
  4. 当数据库发挥作用时,请求A放弃了对Node线程的控制
  5. 请求B进来。
  6. Sails获取请求B的会话并将其存储在全局$_SESSION对象中。
  7. 请求B放弃对线程的控制以执行其他异步调用。
  8. 请求A返回其数据库调用的结果,并从$_SESSION对象中读取内容。
  9. 你可以在这里看到问题 - 请求A现在有错误的会话数据。这就是为什么会话对象存在于请求对象内部的原因,以及为什么需要将它传递给任何想要使用它的代码。努力避免这种情况将不可避免地导致麻烦。

答案 1 :(得分:0)

我能想到的最佳选择是利用JS,并创建一些全局可访问的函数。

但它会产生代码味道:(

答案 2 :(得分:0)

我更喜欢制定一个在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, '/');
    };