javascript - How to expose your models to the app and to routes -
i using waterline orm express. wondering best way expose models can use them in app. far have call req.app.models.model_name
seems bit complicated. code example works i'm not sure if practice since i'm quite new node.js / waterline , express.
my folder structure 1 made express generator modifications:
├── 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
this how use waterline inside models. have index.js setup waterline , automatically loads other models in folder ./models
// ./models/index.js var orientadapter = require('sails-orientdb'); var waterline = require('waterline'); var orm = new waterline(); var config = { // setup adapters // creates named adapters have have been required adapters: { 'default': orientadapter, orient: orientadapter, }, // build connections config // setup connections using named adapter configs connections: { mylocalorient: { adapter: 'orient', host: 'localhost', port: 2424, user: 'root', password: 'password', database: 'database' } }, defaults: { migrate: 'alter' } }; // include 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};
an example model (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;
to hook app modified ./bin/www
use start app (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'); /** * port environment , 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 network interfaces. */ // start server startup 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 port 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 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 friendly messages switch (error.code) { case 'eacces': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'eaddrinuse': console.error(bind + ' in use'); process.exit(1); break; default: throw error; } } /** * event listener http server "listening" event. */ function onlistening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('listening on ' + bind); }
i can use models in routes so:
// ./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;
note use of req.app.models.link.find()...
.
i started worried when tried hook in passport , created file ./config/passport.js
. first implementation got error referenceerror: req not defined
had change , pass request object passport strategy. so:
// ./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 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); });
and passport local strategy:
// ./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 user username exists or not req.app.models.user.findone({ 'username' : username }, function(err, user) { // in case of error, return using done method if (err) return done(err); // username not exist, log error & redirect if (!user){ console.log('user not found username '+username); return done(null, false, { message: 'user not found username '+username }); } // user exists wrong password, log error if (!user.verifypassword(password)){ console.log('invalid password'); return done(null, false, { message: 'invalid password'}); } // user , password both match, return user // done method treated success return done(null, user); } ); }));
maybe fine wondering if there better way this.
question: way expose waterline models app? or missing something?
Comments
Post a Comment