2012-02-10 37 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