2014-04-04 14 views
5

Questa è un'estensione di this question.sails.js Utilizzare il parametro di sessione nel modello

Nei miei modelli, ognuno richiede una società da impostare sulla creazione e ognuno richiede che i modelli vengano filtrati dalla stessa sessione tenuta in azienda.

Con sails.js, ho letto e compreso che la sessione non è disponibile nel modello a meno che non la inietti utilizzando il controller, tuttavia questo richiederebbe che io codifichi tutti i miei controller/azioni con qualcosa di molto, molto ripetitivo. Sfortunato.

Mi piace sails.js e voglio fare il passaggio, ma qualcuno può descrivermi un modo migliore? Spero di aver appena perso qualcosa.

risposta

12

Quindi, se ho capito bene, si vuole evitare un sacco di codice come questo nel vostro controller:

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

Fiera abbastanza Forse. Siamo preoccupati che il nome companyId venga rinominato in futuro o debba essere ulteriormente elaborato. La soluzione più semplice se si stanno utilizzando azioni personalizzate del controller sarebbe quella di creare metodi di classe per i modelli che accettano la richiesta come argomento:

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

D'altra parte, se sei su v0.10.x e puoi utilizzare i progetti per alcune azioni CRUD, potrai beneficiare della capacità di override the blueprints with your own code, in modo che tutte le tue creazioni e i tuoi reperimenti utilizzino automaticamente lo companyId dalla sessione.

Se provieni da uno sfondo non Nodo, tutto questo potrebbe causare un po 'di grattacapi. "Perché non puoi rendere la sessione disponibile ovunque?" potresti chiedere. "COME FACCIANO IN PHP!"

Il motivo è che PHP è senza stato - ogni richiesta che arriva viene essenzialmente una nuova copia dell'app, con niente in memoria che viene condiviso tra le richieste. Ciò significa che qualsiasi variabile globale sarà valida solo per la vita di una singola richiesta. Quel meraviglioso hash $_SESSION è tuo e tuo, e una volta che la richiesta è stata elaborata, scompare.

Contrariamente a ciò con le app di nodo, che essenzialmente vengono eseguite in un unico processo. Qualsiasi variabile globale impostata verrà condivisa tra ogni richiesta e poiché le richieste vengono gestite in modo asincrono, non è possibile garantire che una richiesta venga completata prima dell'avvio di un'altra. Quindi uno scenario come questo potrebbe facilmente verificarsi:

  1. Richiedere un viene in
  2. Sails acquisisce la sessione per Richiedere un e lo memorizza nella $_SESSION oggetto globale..
  3. Richiedere un chiama SomeModel.find(), che chiama a una banca dati in modo asincrono
  4. Mentre il database fa la sua magia, Richiedere un cede il controllo del filo Nodo
  5. Richiesta B entra in gioco.
  6. Sails acquisisce la sessione per la richiesta B e la memorizza nell'oggetto globale $_SESSION.
  7. La richiesta B rende il controllo del thread per eseguire un'altra chiamata asincrona.
  8. La richiesta A ritorna con il risultato della sua chiamata al database e legge qualcosa dall'oggetto $_SESSION.

È possibile visualizzare il problema qui - Richiesta A ha ora i dati di sessione sbagliati. Questo è il motivo per cui l'oggetto di sessione risiede all'interno dell'oggetto di richiesta e perché deve essere passato a qualsiasi codice che lo voglia utilizzare. Cercare troppo difficile per aggirare questo porterà inevitabilmente a problemi.

+0

che è quanto di più completo e risposta come si può ottenere. – Meeker

+0

Scott: puoi indicare alcuni documenti che mostrano questi override di progetti? Sto cercando ma forse non abbastanza difficile. – Meeker

+0

I documenti sono ancora incompleti per la versione beta, ma la [risposta I collegata a] (http://stackoverflow.com/questions/22273789/crud-blueprint-overriding-in-sailsjs/22274325#22274325) dovrebbe iniziare. – sgress454

0

La migliore opzione che posso pensare è sfruttare JS e creare alcune funzioni accessibili a livello globale.

Ma la sua gonna hanno un odore di codice :(

0

preferisco fare una politica che aggiungere il CompanyID all'interno del body.param in questo modo:

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