我的mongoose模型定义如下:
user.js的
module.exports = function() {
var mongoose = require('mongoose');
// Creates a new Mongoose Schema object
var Schema = mongoose.Schema;
// Collection to hold users
var UserSchema = new Schema({
username: { type: String, required: true },
password: { type: String, required: true },
},{
versionKey: false
}
);
// Creates the Model for the User Schema
var User = mongoose.model('User', UserSchema);
var getUserById = function(id, callback) {
User.findById(id, callback);
}
var getUserByUsername = function(username, callback) {
var query = {username: username};
User.findOne(query, callback);
}
return {
getUserById: getUserById,
getUserByUsername: getUserByUsername
}
}()
基本上我正在返回User模型的客户端可以使用的公共接口。 I.E.我的用户路由抓取模型,可以调用定义的两个公共方法,而不是其他任何东西。我这样做是为了抽象我在路线上使用mongodb / mongoose的事实。我很可能会有一个User模型在某些时候与postgres交谈,或者可能只是切换到postgres。因此,我不想查看调用mongoose特定函数的routes方法中的位置代码。
这是我的问题。当我需要一个模块时,代码中的大多数地方都会调用
var someUtil = require('./someUtil');
但是,如果我为一个猫鼬模型多次这样做,我会收到一个错误,指出它无法定义两次。
var User = require('./user'); // Cannot put this in more than one file without getting an error.
是否有更好的方法来编写user.js文件,以便我可以为我的用户模型提供公共接口,但只定义一次Schema,以便我可以在该文件上调用多次?
答案 0 :(得分:3)
你应该将Mongoose模型与你用它包装的服务分开。
我建议你有一个模型文件夹,每个模式有1个文件,每个文件看起来都像这样:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema
var User = new Schema({
...fields your schema will have
})
//additional virtuals or configuration
module.exports = mongoose.model('User', User)
然后有一个services
文件夹,其中UserService需要该模型:
var User = require('../models/User')
function UserService(){
//create User, delete User, etc.
}
module.exports = new UserService()
然后从现在开始在您的控制器或路由中只需要UserService。你不会遇到这类问题而且你的代码组织得更好。
答案 1 :(得分:0)
我也遇到过这个问题。
您可以做的事情是将模式定义包装在try catch
中将此行var User = mongoose.model('User', UserSchema);
替换为:
var User;
try {
User = mongoose.model('User', UserSchema);
}
catch(e) {
User = mongoose.model('User');
}
不确定它是否是最佳方式,但它会起作用。
答案 2 :(得分:0)
Andreas是对的:
AFAIK node caches the result of requireing a module, and thus the above function should not be run twice. Other than that there's no reason to wrap you code in a self-executing function, just expose the methods like exports.getUserById = getUserById; //etc.
答案 3 :(得分:0)
我遇到了这个问题,我想我会贡献我的答案。我遇到的问题稍微复杂一点,因为我已经反对了#39;我的架构中的定义。我还没有达到"为什么"但基本上发生的事情是,依赖链导致节点需要两次相同的文件。这已经过验证,因为我得到了两次console.log输出。我之前的方法是简单地导出模式而不是模型,但这很烦人,因为我必须在执行开始时引导所有模型。经过一些修补,我决定使用这个范例(使用coffeescript):
Mongoose = require 'mongoose'
unless 'Foo' in Mongoose.modelNames()
schema = new Mongoose.Schema
bar: String
Mongoose.model 'Foo', schema
module.exports = Mongoose.model 'Foo'
答案 4 :(得分:0)
在你定义 express 的 index.js 之上的其他任何东西之前,你只需要一次猫鼬模型:
require('./models/User');
const express = require('express');
然后在应用程序的其他部分,您可以按如下方式访问此模型:
const mongoose = require('mongoose');
const User = mongoose.model('User');
由于我们需要 index.js 中的模型,因此执行了这行代码:mongoose.model('User', userSchema)
,现在可以在应用程序的任何位置访问它