2014-04-04 75 views
5

這是this question的擴展。sails.js在模型中使用會話參數

在我的模型中,每個人都需要在創建時設置companyId,並且每個人都需要通過持有同一會話的companyid過濾模型。

sails.js,我已經閱讀並理解會話在模型中不可用,除非我使用控制器注入會話,但是這需要我用非常非常重複的代碼來編寫所有控制器/動作。不幸的。

我喜歡sails.js並想切換,但任何人都可以向我描述一個更好的方法?我希望我錯過了一些東西。

回答

12

所以,如果我理解正確的話,你要避免很多類似這樣的代碼在你的控制器:

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

不夠公平也許你。如果您使用自定義控制器操作,最簡單的解決方案是將您的模型的類方法接受請求作爲參數:

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

另一方面,如果您使用v0.10.x並且可以使用藍圖進行某些CRUD操作,則您將受益於override the blueprints with your own code的能力,以便您創建和發現的所有內容都自動使用companyId來自會議。

如果您來自非節點背景,這可能會導致一些頭部劃傷。 「爲什麼你不能讓會議在任何地方都可以使用?」你可能會問。 「他們喜歡用PHP做!」

原因是PHP是無狀態 - 每一個進來的請求基本上都得到了應用程序的新副本,在請求之間沒有任何內存被共享。這意味着任何全局變量只對一個請求的生命有效。那個美妙的$_SESSION散列是你自己和你的散列,一旦請求被處理,它就會消失。

將此與Node應用程序進行對比,該應用程序基本上在單個進程中運行。您設置的任何全局變量都將在每個進入的請求之間共享,並且由於請求是異步處理的,所以不能保證一個請求會在另一個請求開始之前完成。因此,像這樣的情況可能很容易發生:

  1. 請求A進來
  2. 帆獲得全球$_SESSION對象請求A,並將其存儲會話。
  3. 請求A調用SomeModel.find(),它調用了到數據庫異步
  4. 當數據庫做它的魔力,可要求其投降的節點螺紋
  5. 請求B進來的控制。
  6. Sails獲取請求B的會話並將其存儲在全局對象$_SESSION中。
  7. 請求B放棄對其線程的控制來執行其他異步調用。
  8. 請求A返回其數據庫調用結果,並從$_SESSION對象讀取某些內容。

您可以在這裏看到問題 - 請求A現在有錯誤的會話數據。這就是會話對象駐留在請求對象內部的原因,以及爲什麼需要將它傳遞給任何想要使用它的代碼。試圖繞開這一難題將不可避免地導致麻煩。

+0

這大約是完整和答案,你可以得到。 – Meeker

+0

斯科特 - 你能指出一些顯示這些藍圖覆蓋的文檔嗎?我正在尋找,但可能並不夠難。 – Meeker

+0

文檔對於測試版本仍然不完整,但[鏈接到的答案](http://stackoverflow.com/questions/22273789/crud-blueprint-overriding-in-sailsjs/22274325#22274325)應該讓你開始。 – sgress454

0

我能想到的最佳選擇是利用JS,並創建一些全局可訪問的功能。

但它就要有一個代碼味道:(

0

我更願意作出這樣的添加companyId的body.param內像這樣的政策:

// 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, '/'); 
    };