Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

This is an extension of this question.

In my models, every one requires a companyId to be set on creation and every one requires models to be filtered by the same session held companyid.

With sails.js, I have read and understand that session is not available in the model unless I inject it using the controller, however this would require me to code all my controller/actions with something very, very repetitive. Unfortunate.

I like sails.js and want to make the switch, but can anyone describe to me a better way? I'm hoping I have just missed something.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
318 views
Welcome To Ask or Share your Answers For Others

1 Answer

So, if I understand you correctly, you want to avoid lots of code like this in your controllers:

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

Fair enough. Maybe you're concerned that companyId will be renamed in the future, or need to be further processed. The simplest solution if you're using custom controller actions would be to make class methods for your models that accept the request as an argument:

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

On the other hand, if you're on v0.10.x and you can use blueprints for some CRUD actions, you will benefit from the ability to override the blueprints with your own code, so that all of your creates and finds automatically use the companyId from the session.

If you're coming from a non-Node background, this might all induce some head-scratching. "Why can't you just make the session available everywhere?" you might ask. "LIKE THEY DO IN PHP!"

The reason is that PHP is stateless--every request that comes in gets essentially a fresh copy of the app, with nothing in memory being shared between requests. This means that any global variables will be valid for the life of a single request only. That wonderful $_SESSION hash is yours and yours alone, and once the request is processed, it disappears.

Contrast this with Node apps, which essentially run in a single process. Any global variables you set would be shared between every request that comes in, and since requests are handled asynchronously, there's no guarantee that one request will finish before another starts. So a scenario like this could easily occur:

  1. Request A comes in.
  2. Sails acquires the session for Request A and stores it in the global $_SESSION object.
  3. Request A calls SomeModel.find(), which calls out to a database asynchronously
  4. While the database does its magic, Request A surrenders its control of the Node thread
  5. Request B comes in.
  6. Sails acquires the session for Request B and stores it in the global $_SESSION object.
  7. Request B surrenders its control of the thread to do some other asynchronous call.
  8. Request A comes back with the result of its database call, and reads something from the $_SESSION object.

You can see the issue here--Request A now has the wrong session data. This is the reason why the session object lives inside the request object, and why it needs to be passed around to any code that wants to use it. Trying too hard to circumvent this will inevitably lead to trouble.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...