Javascript 如何向应用程序和路由公开您的模型

Javascript 如何向应用程序和路由公开您的模型,javascript,node.js,express,orientdb,waterline,Javascript,Node.js,Express,Orientdb,Waterline,我和Express一起使用作为我的ORM。我想知道什么是最好的方式是公开我的模型,这样我就可以在我的应用程序中使用它们。到目前为止,我不得不调用req.app.models.model\u name,这似乎有点复杂。这个代码示例很有效,但我不太确定这是否是一个好的实践,因为我对Node.js/Waterline和Express还很陌生 我的文件夹结构是由express generator制作的,经过一些修改: ├── app.js ├── bin │ └── www ├── models │

我和Express一起使用作为我的ORM。我想知道什么是最好的方式是公开我的模型,这样我就可以在我的应用程序中使用它们。到目前为止,我不得不调用
req.app.models.model\u name
,这似乎有点复杂。这个代码示例很有效,但我不太确定这是否是一个好的实践,因为我对Node.js/Waterline和Express还很陌生

我的文件夹结构是由express generator制作的,经过一些修改:

├── app.js
├── bin
│   └── www
├── models
│   ├── index.js
│   └── links.js
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.jade
    ├── index.jade
    └── layout.jade
这就是我在模型中使用水线的方式。我有一个index.js来设置Waterline,它会自动加载文件夹
/models

// ./models/index.js

var orientAdapter = require('sails-orientdb');
var Waterline = require('waterline');

var orm = new Waterline();

var config = {
  // Setup Adapters
  // Creates named adapters that have have been required
  adapters: {
    'default': orientAdapter,
    orient: orientAdapter,
  },

  // Build Connections Config
  // Setup connections using the named adapter configs
  connections: {
    myLocalOrient: {
      adapter: 'orient',
      host: 'localhost',
      port: 2424,
      user: 'root',
      password: 'password',
      database: 'database'
    }
  },

  defaults: {
    migrate: 'alter'
  }
};

// Include all files in ./models directory
var fs = require('fs');
var path = require("path");

fs
  .readdirSync(__dirname)
  .filter(function(file) {
    return (file.indexOf(".") !== 0) && (file !== "index.js");
  })
  .forEach(function(file) {
    var model = require(path.join(__dirname, file));
    orm.loadCollection(model);
  });

module.exports = {waterline: orm, config: config};
示例模型(
链接
):

要将其挂接到我的应用程序中,我修改了用于启动应用程序的
/bin/www
节点。/bin/www

我现在可以在我的路线中使用以下模型:

// ./routes/index.js    

var express = require('express');
var router = express.Router();
var app = require('../app');

// Index
router.get('/links', function(req, res, next) {
    req.app.models.link.find().limit(10).then(function(links) { 
        res.json(links); 
    });
});

// Create
router.post('/links', function(req, res, next) {
    var link = req.app.models.link.create(req.body)
    .then(function(link) {
        res.json(link);     
    })
    .catch(console.error);
});

module.exports = router;
注意使用了
req.app.models.link.find()…

当我尝试连接并创建一个文件
/config/passport.js
时,我开始担心这个问题。在我的第一个实现中,我得到了一个错误
ReferenceError:req没有定义
,因此我必须更改它并将请求对象传递到我的passport策略中。像这样:

// ./routes/index.js

// ...

// Login User
router.post('/login', function(req, res, next){
  if(!req.body.username || !req.body.password){
    return res.status(400).json({message: 'Please fill out all fields'});
  }

  passport.authenticate('local', function(err, user, info){
    if(err){ return next(err); }

    if(user){
      return res.json({token: user.generateJWT()});
    } else {
      return res.status(401).json(info);
    }
  })(req, res, next);
});
以及我的护照本地策略:

// ./config/passport.js

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy({
    passReqToCallback : true
  },
  function(req, username, password, done) { 
    // check in orientdb if a user with username exists or not
    req.app.models.user.findOne({ 'username' :  username }, 
      function(err, user) {
        // In case of any error, return using the done method
        if (err) return done(err);
        // Username does not exist, log error & redirect back
        if (!user){
          console.log('User Not Found with username '+username);
          return done(null, false, { message: 'User Not Found with username '+username });                 
        }
        // User exists but wrong password, log the error 
        if (!user.verifyPassword(password)){
          console.log('Invalid Password');
          return done(null, false, { message: 'Invalid Password'});
        }
        // User and password both match, return user from 
        // done method which will be treated like success
        return done(null, user);
      }
    );
}));
也许这很好,但我想知道是否有更好的方法来做到这一点


问题:这是向我的应用程序公开水线模型的好方法吗?还是我遗漏了什么?

您已经有了对
app
的引用,无需转到
req
获取它。此外,您可以在顶部存储对
Link
的引用,以便直接将其用作
Link
,而不是
app.models.Link
,而无需更改任何其他内容。@KevinB好吧,不太好。如果我试图在
/config/passport.js
中直接引用应用程序,我会得到错误
ReferenceError:app未定义
。如果我试图在顶部引用它,也是一样的。或者“您已经有了对app的引用”是什么意思?
var-app=require(“../app”)在您的路线中,它已经存在。
var-app=require('../app'),user=app.models.user导致
无法读取未定义的属性“user”
,因为模型在
/bin/www
中提供。是的,您需要确保在使用模型之前对其进行了初始化。使用
app
跟踪它们看起来是在应用程序中共享模型的好方法。
// ./routes/index.js

// ...

// Login User
router.post('/login', function(req, res, next){
  if(!req.body.username || !req.body.password){
    return res.status(400).json({message: 'Please fill out all fields'});
  }

  passport.authenticate('local', function(err, user, info){
    if(err){ return next(err); }

    if(user){
      return res.json({token: user.generateJWT()});
    } else {
      return res.status(401).json(info);
    }
  })(req, res, next);
});
// ./config/passport.js

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy({
    passReqToCallback : true
  },
  function(req, username, password, done) { 
    // check in orientdb if a user with username exists or not
    req.app.models.user.findOne({ 'username' :  username }, 
      function(err, user) {
        // In case of any error, return using the done method
        if (err) return done(err);
        // Username does not exist, log error & redirect back
        if (!user){
          console.log('User Not Found with username '+username);
          return done(null, false, { message: 'User Not Found with username '+username });                 
        }
        // User exists but wrong password, log the error 
        if (!user.verifyPassword(password)){
          console.log('Invalid Password');
          return done(null, false, { message: 'Invalid Password'});
        }
        // User and password both match, return user from 
        // done method which will be treated like success
        return done(null, user);
      }
    );
}));