You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a single models.js module that I'd like to load in both Express request handlers and non-Express code. It would be nice if the function definitions for these two cases could be similar so that the models.exports function could be written once well.
Express expects a function with db and models as an argument:
+1 this needs to be solved as it's causing confusion.
The whole idea of integrating model definitions into express has bugged me from the begining. People get really confused when they need to eg have a "sync" task runnable from the command line.
I omit the built in methods of loading altogether as they don't work how I'd like.
We could probably integrate db.load into the above, and provide a simple middleware to add req.db and req.models.
I'm also planning to add a simple example app with express, a sync task, and some basic functionality so that people have an easy template to follow, as issues like this one keep coming up.
db.load's callbacks work fine, which means I can essentially 'block' until db has synced. The express middleware, on the other hand, does not expose access to the next() call in order to chain callbacks.
The issue here is that the below does not work:
exports.express = function(db, models) {
load(db, function() { // will be called once db.sync() completes
_.extend(models, db.models);
});
};
In unit testing with my test database, the request is executed quick enough that request.models is not set in the callback above. More accurately, it isn't set until after the test fails, but you know.
I'm not sure this extra middleware is worth it in the current state.
models/index.js has a bug; Since db.load is asynchronous, it means return fn() could be called first, and then once the async load finishes (with an error) it would call fn a second time.
That said, I'm not convinced that load needs to be async in the first place.
I've started work on the example app, but nothing to show just yet. Once it's done will have a discussion with everyone and hopefully update the api+docs.
db.load was created as async because you could have your model definition remotely or given by a service or something. The first part does a require of the given path but then the function called can take some time. The Express part should be changed to be async too.
@colegleason please try this latest commit. If you define your function with a 3rd argument it will assume it's a next callback that you call when everything is loaded.
Just a heads up, this should be updated in the readme as I had a pretty hard time figuring out how to declare it the correct way using the middleware (and not all in my app.js file)
varasync=require('async'),definedModels;module.exports.define=function(db,models,next){definedModels=models;varcurriedLoad=function(file){returnfunction(cb){db.load(file,cb);};};async.waterfall([curriedLoad('.model/user'),curriedLoad('.model/posting'),// ...],function(err){db.models.user.hasMany(db.models.posting);db.sync(next);});};// I use passport.js and need models without being able to access them through the request object.module.exports.model=function(name){returndefinedModels[name];}
Activity
dxg commentedon Aug 11, 2013
+1 this needs to be solved as it's causing confusion.
The whole idea of integrating model definitions into express has bugged me from the begining. People get really confused when they need to eg have a "sync" task runnable from the command line.
Personally, I use something like this:
I omit the built in methods of loading altogether as they don't work how I'd like.
We could probably integrate
db.loadinto the above, and provide a simple middleware to add req.db and req.models.I'm also planning to add a simple example app with express, a sync task, and some basic functionality so that people have an easy template to follow, as issues like this one keep coming up.
colegleason commentedon Aug 13, 2013
I'm running into more issues here.
db.load's callbacks work fine, which means I can essentially 'block' until db has synced. The express middleware, on the other hand, does not expose access to the
next()call in order to chain callbacks.The issue here is that the below does not work:
In unit testing with my test database, the request is executed quick enough that request.models is not set in the callback above. More accurately, it isn't set until after the test fails, but you know.
I'm not sure this extra middleware is worth it in the current state.
grahamreeds commentedon Aug 14, 2013
I use
where my models/index.js looks like
Could be neater (especially the exports) but works for me.
dxg commentedon Aug 14, 2013
models/index.js has a bug; Since
db.loadis asynchronous, it meansreturn fn()could be called first, and then once the asyncloadfinishes (with an error) it would callfna second time.That said, I'm not convinced that
loadneeds to be async in the first place.I've started work on the example app, but nothing to show just yet. Once it's done will have a discussion with everyone and hopefully update the api+docs.
dresende commentedon Aug 19, 2013
db.loadwas created as async because you could have your model definition remotely or given by a service or something. The first part does arequireof the given path but then the function called can take some time. The Express part should be changed to be async too.Updates express middleware to support async definitions (#291)
dresende commentedon Aug 20, 2013
@colegleason please try this latest commit. If you define your function with a 3rd argument it will assume it's a
nextcallback that you call when everything is loaded.SamuelBolduc commentedon Aug 22, 2013
Just a heads up, this should be updated in the readme as I had a pretty hard time figuring out how to declare it the correct way using the middleware (and not all in my app.js file)
ptnplanet commentedon Aug 24, 2013
I just want to share my solution:
File stack.js
File model.js
dresende commentedon Aug 26, 2013
This will pass to the readme or the wiki as soon as we release a new version.