2014-04-04 9 views
5

Jest to rozszerzenie this question.sails.js Użyj parametru sesji w modelu

W moich modelach każdy z nich wymaga ustawienia identyfikatora firmy na tworzenie, a każdy wymaga odfiltrowania modeli przez tę samą sesję.

Z sails.js, przeczytałem i rozumiem, że sesja nie jest dostępna w modelu, chyba że wstrzyknę to za pomocą kontrolera, jednak wymagałoby to, żebym zakodował cały mój kontroler/akcje z czymś bardzo, bardzo powtarzalnym. Niefortunny.

Podoba mi się sails.js i chcę zmienić, ale czy ktoś może mi lepiej opisać? Mam nadzieję, że właśnie coś przeoczyłem.

Odpowiedz

12

Więc jeśli dobrze rozumiem zostanie poprawnie, chcesz uniknąć dużo kodu jak ten w kontrolerach:

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

Fair enough Może. "obawia się, że companyId zostanie zmieniona w przyszłości, lub musi być dalej przetwarzane. Najprostszym rozwiązaniem, jeśli używasz niestandardowych działań kontrolera, byłoby stworzenie metod klasy dla modeli, które akceptują żądanie jako argument:

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

Z drugiej strony, jeśli korzystasz z wersji v0.10.x i możesz korzystać ze schematów dla niektórych działań CRUD, będziesz mógł korzystać z możliwości override the blueprints with your own code, dzięki czemu wszystkie twoje utworzone i znalezione automatycznie używają companyId z sesji.

Jeśli pochodzisz z tła innego niż Węzeł, może to wywołać pewne drapanie głowy. "Dlaczego nie możesz udostępnić sesji w dowolnym miejscu?" możesz zapytać. "JAKIE ZROBIĄ W PHP!"

Powodem jest to, że PHP to bezpaństwowiec - każda prośba, która przychodzi, jest w zasadzie nową kopią aplikacji, w której nic nie jest współużytkowane między żądaniami. Oznacza to, że wszelkie zmienne globalne będą ważne przez cały okres jednego żądania. Ten wspaniały kod mieszany $_SESSION jest twój i twój, a po przetworzeniu żądania znika.

Należy to porównać z aplikacjami węzła, które zasadniczo działają w jednym procesie. Wszystkie ustawione zmienne globalne będą współdzielone między każdym żądanym zgłoszeniem, a ponieważ żądania są obsługiwane asynchronicznie, nie ma gwarancji, że jedno żądanie zakończy się przed rozpoczęciem kolejnego. Tak jak ten scenariusz może łatwo wystąpić:

  1. zażądać przychodzi
  2. Sails nabywa sesję dla zażądać i zapisuje go w globalnej $_SESSION obiektu..
  3. zażądać wzywa SomeModel.find(), który woła do bazy danych asynchronicznie
  4. Podczas gdy baza danych ma swoją magię, zażądać podporządkowuje swoją kontrolę wątku Node
  5. Zapytanie B wchodzi.
  6. Żagle uzyskują sesję dla żądania B i przechowuje ją w globalnym obiekcie $_SESSION.
  7. Żądanie B przekazuje kontrolę nad wątkiem, aby wykonać inne wywołanie asynchroniczne.
  8. Żądanie A wraca z wynikiem połączenia z bazą danych i odczytuje coś z obiektu $_SESSION.

Możesz zobaczyć problem tutaj - Żądanie A ma teraz nieprawidłowe dane sesji. To jest powód, dla którego obiekt sesji żyje wewnątrz obiektu żądania i dlaczego musi zostać przekazany do dowolnego kodu, który chce go użyć. Zbyt trudne próby obejścia tego nieuchronnie doprowadzą do kłopotów.

+0

że jest tak kompletna i odpowiedź, jak można dostać. – Meeker

+0

Scott - czy możesz wskazać jakieś dokumenty, które pokazują nadpisania planów? Szukam, ale może nie dość mocno. – Meeker

+0

Dokumenty są nadal niekompletne w wersji beta, ale odpowiedź [answer I linked to] (http://stackoverflow.com/questions/22273789/crud-blueprint-overriding-in-sailsjs/22274325#22274325) powinna Cię uruchomić. – sgress454

0

Najlepszą opcją, o której mogę pomyśleć, jest skorzystanie z JS i udostępnienie globalnie dostępnych funkcji.

Ale jego gonna mają zapach kodu :(

0

wolę uczynić politykę, która dodać companyId wewnątrz body.param tak:

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