2012-02-10 39 views
51

我目前在我的Mongoose/NodeJS应用程序的/models/models.js文件中有所有模型(模式定义)。Mongoose&NodeJS项目的文件结构

我想分离这些成不同的文件,例如:user_account.js,profile.js等,但我似乎无法这样做,因为我的控制器打破,并报告“找不到模块”一次我把这些课分开。

我的项目结构如下:

/MyProject 
    /controllers 
    user.js 
    foo.js 
    bar.js 
    // ... etc, etc 
    /models 
    models.js 
    server.js 

我models.js文件的内容是这样的:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 

mongoose.connect('mongodb://localhost/mydb'); 

var UserAccount = new Schema({ 
    user_name  : { type: String, required: true, lowercase: true, trim: true, index: { unique: true } }, 
    password  : { type: String, required: true }, 
    date_created : { type: Date, required: true, default: Date.now } 
}); 

var Product = new Schema({ 
    upc    : { type: String, required: true, index: { unique: true } }, 
    description  : { type: String, trim: true }, 
    size_weight  : { type: String, trim: true } 
}); 

我user.js的文件(控制器)看起来是这样的:

var mongoose = require('mongoose'), 
    UserAccount = mongoose.model('user_account', UserAccount); 

exports.create = function(req, res, next) { 

    var username = req.body.username; 
    var password = req.body.password; 

    // Do epic sh...what?! :) 
} 

如何将模式定义分解为多个文件并从我的控件中引用它米勒?当我引用它(后模式是在一个新的文件),我得到这个错误:

*错误:架构尚未注册模式“USER_ACCOUNT” *

的思考?

+1

我写猫鼬胶模块,可以帮助组织你的猫鼬型号:https://开头github.com/xpepermint/mongoose-glue – xpepermint 2014-08-30 17:10:40

回答

88

下面是一个示例app/models/item.js

var mongoose = require("mongoose"); 

var ItemSchema = new mongoose.Schema({ 
    name: { 
    type: String, 
    index: true 
    }, 
    equipped: Boolean, 
    owner_id: { 
    type: mongoose.Schema.Types.ObjectId, 
    index: true 
    }, 
    room_id: { 
    type: mongoose.Schema.Types.ObjectId, 
    index: true 
    } 
}); 

var Item = mongoose.model('Item', ItemSchema); 

module.exports = { 
    Item: Item 
} 

要从app/controllers/items.js项目控制器加载这个我会做

var Item = require("../models/item").Item; 
    //Now you can do Item.find, Item.update, etc 

换句话说,同时定义架构和模型模块中的模型和然后导出模型。使用相对需求路径将模型模块加载到您的控制器模块中。

要建立连接,请在服务器启动代码(server.js或其他)中尽早处理。通常,您需要从配置文件或环境变量读取连接参数,如果未提供配置,则默认为开发模式localhost。

var mongoose = require('mongoose'); 
mongoose.connect('mongodb://localhost'); 
+0

连接代码怎么样?如何将其包含在单独的代码中 – 2013-01-12 14:54:24

+4

我更新了我的答案以解决该问题。 – 2013-01-12 20:49:34

+2

就这么简单?大声笑 – ShrekOverflow 2013-03-11 11:19:47

8

彼得里昂几乎涵盖了基础。从上面的例子中(去除模式之后的线)
借用我只是想补充:

app/models/item.js

note: notice where `module.exports` is placed 
var mongoose = require("mongoose"); 

var ItemSchema = module.exports = new mongoose.Schema({ 
    name: { 
    type: String, 
    index: true 
    }, 
    ... 

}); 

要从没有所述app/controllers/items.js

var mongoose = require('mongoose'); 
var Item = mongoose.model('Item', require('../models/item')); 

另一种方式加载它module.exportsrequire

app/models/item.js

var mongoose = require("mongoose"); 

var ItemSchema = new mongoose.Schema({ 
    name: { 
    type: String, 
    index: true 
    }, 
    ... 

}); 

mongoose.model('Item', ItemSchema); // register model 

在这里的app/controllers/items.js

var mongoose = require('mongoose') 
    , Item = mongoose.model('Item'); // registered model 
+0

控制器将从何处被调用? – Warz 2013-03-13 01:31:15

+0

不知道我理解你的问题。你能澄清吗? – user1460015 2013-04-17 18:01:07

35

一对夫妇的答案真的帮助我发展的另一种方法。原来的问题是关于打破只是的架构定义,但我更愿意将架构和模型定义绑定在同一个文件中。

这主要是彼得的想法,只有通过覆盖module.exports使访问来自您的控制器型号少一些冗长导出模型定义:

项目布局:

MyProject 
    /controllers 
    user.js 
    foo.js 
    bar.js 
    // ... etc, etc 
    /models 
    Item.js 
    server.js 

型号/项目.js文件看起来像:

var mongoose = require("mongoose"); 

var ItemSchema = new mongoose.Schema({ 
    name: { 
    type: String, 
    index: true 
    } 
}); 

module.exports = mongoose.model('Item', ItemSchema); 
// Now `require('Item.js')` will return a mongoose Model, 
// without needing to do require('Item.js').Item 

并访问模型控制器,说user.js的,如:

var Item = require(__dirname+'/../models/Item') 

... 

var item = new Item({name:'Foobar'}); 

不要忘记调用server.js mongoose.connect(..),或其他任何地方,你认为合适的!

9

我最近回答了关于同样问题的Quora问题。 http://qr.ae/RoCld1

我发现非常好,节省的量需要电话是你的模型构建成一个单一的目录中。确保每个文件只有一个模型。

在与模型相同的目录中创建一个index.js文件。将此代码添加到它。一定要添加必要的FS需要

var fs = require('fs'); 

/* 
* initializes all models and sources them as .model-name 
*/ 
fs.readdirSync(__dirname).forEach(function(file) { 
    if (file !== 'index.js') { 
    var moduleName = file.split('.')[0]; 
    exports[moduleName] = require('./' + moduleName); 
    } 
}); 

现在你可以调用所有的型号如下:

var models = require('./path/to/models'); 
var User = models.user; 
var OtherModel = models['other-model']; 
+1

这是迄今为止最好的答案,自动化可以在代码中节省大量冗余,并且最终看起来非常干净。 – zoubida13 2016-06-19 15:02:52

+0

我假设你有你的数据库初始化代码在项目的根。任何想法如何执行?谢谢 – 2016-07-02 18:16:33