如何将您的模型展示给应用程序和路线

我使用Waterline作为我的ORM和Express一起使用。 我想知道什么是最好的方式是揭露我的模型,所以我可以在我的应用程序中使用它们。 到目前为止,我必须调用req.app.models.model_name这似乎有点复杂。 这个代码示例工程,但我只是不太确定这是否是一个很好的做法,因为我是Node.js / Waterline和Express的新手。

我的文件夹结构是由expression式生成器做的一些修改:

 ├── 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 

这就是我在模型中使用Waterline的方式。 我有一个index.js来设置水线,它会自动加载文件夹./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}; 

示例模型( Link ):

 // ./models/link.js var Waterline = require('Waterline'); var orientAdapter = require('sails-orientdb'); var Link = Waterline.Collection.extend({ identity: 'link', connection: 'myLocalOrient', attributes: { title: { type: 'string', required: true }, url: { type: 'string', required: true } } }); module.exports = Link; 

挂钩到我的应用程序我修改./bin/www你用来启动应用程序( node ./bin/www

 // ./bin/www #!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var debug = require('debug')('v2:server'); var http = require('http'); /** * Get port from environment and store in Express. */ var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /** * Create HTTP server. */ var server = http.createServer(app); /** * Listen on provided port, on all network interfaces. */ // START SERVER STARTUP WITH WATERLINE var models = require('../models'); models.waterline.initialize(models.config, function(err, models) { if(err) throw err; // console.log(models.collections); app.models = models.collections; app.connections = models.connections; // Start Server server.listen(port); server.on('error', onError); server.on('listening', onListening); }); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); } 

我现在可以在我的路线中使用模型,如下所示:

 // ./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()...

当我试图挂接Passport并创build一个文件./config/passport.js时,我开始担心这个问题。 在我的第一个实现中,我得到了错误ReferenceError: req is not defined所以我不得不改变它,并将请求对象传递到我的护照策略。 像这样:

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

也许这是好的,但我想知道是否有更好的方法来做到这一点。

问题:这是将我的水线模型暴露给我的应用程序的好方法吗? 还是我错过了什么?