Mongoose&的文件结构NodeJS项目

时间:2012-02-10 16:15:35

标签: node.js mongoose

我目前在/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”注册架构。*

思考?

6 个答案:

答案 0 :(得分:95)

以下是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');

答案 1 :(得分:35)

这里的几个答案真的帮助我开发了另一种方法。最初的问题是关于打破只是模式定义,但我更喜欢将模式和模型定义捆绑在同一个文件中。

这主要是Peter的想法,只是通过覆盖module.exports来导出模型定义,以便从控制器访问模型一点点简洁:

项目布局:

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

models / Item.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(..),或者在您认为合适的任何地方!

答案 2 :(得分:12)

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

我发现非常好并且节省了 require 调用的数量是将模型构建到单个目录中。确保每个文件只有一个模型。

在与模型相同的目录中创建index.js文件。将此代码添加到其中。请务必添加必要的 fs require

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'];

答案 3 :(得分:8)

Peter Lyons几乎涵盖了基础 借用上面的例子(删除模式后的行)我只想添加:

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

答案 4 :(得分:1)

受sequelize-cli的启发,我有一个模型目录,我定义了所有模式。

在github上完成应用:https://github.com/varunon9/node-starter-app-mongo

模型/ index.js -

'use strict';

const fs        = require('fs');
const path      = require('path');
const mongoose = require('mongoose');//.set('debug', true);
const basename  = path.basename(__filename);
const env       = process.env.NODE_ENV || 'development';
const config    = require(__dirname + '/../config/config.json')[env];
const db        = {};

const Schema = mongoose.Schema;

fs
    .readdirSync(__dirname)
    .filter(fileName => {
        return (
            fileName.indexOf('.') !== 0) 
                    && (fileName !== basename) 
                    && (fileName.slice(-3) === '.js'
        );
    })
    .forEach(fileName => {
        const model = require(path.join(__dirname, fileName));
        const modelSchema = new Schema(model.schema);

        modelSchema.methods = model.methods;
        modelSchema.statics = model.statics;

        // user.js will be user now
        fileName = fileName.split('.')[0];
        db[fileName] = mongoose.model(fileName, modelSchema);
    });

module.exports = db;

模型/ user.js的 -

'use strict';

module.exports = {
    schema: {
        email: {
            type: String,
            required: true,
            unique: true,
        },
        mobile: {
            type: String,
            required: false
        },
        name: {
            type: String,
            required: false
        },
        gender: {
            type: String,
            required: false,
            default: 'male'
        },
        password: {
            type: String,
            required: true
        },
        dob: {
            type: Date,
            required: false
        },
        deactivated: {
            type: Boolean,
            required: false,
            default: false
        },
        type: {
            type: String,
            required: false
        }
    },

    // instance methods goes here
    methods: {

    },

    // statics methods goes here
    statics: {
    }
};

答案 5 :(得分:0)

我喜欢使用类来组织一切,也许可以尝试以下方法:

const mongoose = require('mongoose')

class UserAccount {
    constructor() {
        this.schema = new mongoose.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 }
        });
        this.model = new mongoose.model('UserAccount', this.schema)
    }

    create = (obj) => {
        return new Promise((resolve, reject) => {
            this.model.create({ ...item })
                .then((result) => {
                    resolve(result)
                }).catch((err) => {
                    reject(err)
                });
        });
    }
}

module.exports = UserAccount;

此方法允许您添加自定义方法。另外,它将控制器/模型组合到单个向量中,使您可以随时分离模型。这可能无法在企业中扩展,但可以适合较小的应用程序。