外部模块中的模式在Node.js中不起作用

时间:2014-11-09 05:07:05

标签: node.js mongodb mongoose

我头痛不已,尝试通过模块将一些常见的模式定义共享给我的代码库中的所有其他模块。

我有一个包含这两个模式的myproj_schemas模块:

var mongoose = require('mongoose'),
    util = require("util"),
    Schema = mongoose.Schema;

var BaseProfileSchema = function() {
    Schema.apply(this, arguments);

    this.add({
        _user: {type: Schema.Types.ObjectId, ref: 'User', required: true},
        name: {type: String, required: true},
        bio: {type: String, required: true},
        pictureLink: String
    });

};
util.inherits(BaseProfileSchema, Schema);

module.exports = BaseProfileSchema;

var mongoose = require('mongoose'),
    BaseProfileSchema = require('./base_profile_schema.js'),
    Schema = mongoose.Schema;

var entSchemaAdditions = {
    mentors: {type: Schema.Types.ObjectId, ref: 'Mentor'}
};


var entrepreneurSchema = new BaseProfileSchema(entSchemaAdditions);

module.exports = entrepreneurSchema;

导师也在另一个档案中定义。

我的单元测试这两个都在模式模块中工作。

当我安装此模块并尝试使用

创建时
Entrepreneur = db.model('Entrepreneur', entrepreneurSchema),

我收到以下错误:

TypeError:paths.mentors处的未定义类型   你尝试过嵌套Schemas吗?您只能使用refs或数组进行嵌套。

如果我在本地模块中使用相同的代码,那么没问题。 如果我直接在require中引用模式文件(例如require(' ../ node_modules / myproj_schemas / models / ent_schema'),那么我就会收到错误。

我相当确定它不会像以前那样破坏,但我已经撤消了所有的更改,但它仍然无效。

我画了一个完整的空白,我们将非常感激地收到任何建议。

编辑:

我创建了一个新的Schemas模块。它有一个架构:

var mongoose = require('mongoose');

var userSchema = new mongoose.Schema({
    email: String
});

module.exports = userSchema;

当在模块中打包并且npm安装到其他模块时,这也会失败。

在OS X上运行

3 个答案:

答案 0 :(得分:7)

就个人而言,我创建了单独的" common"使用init方法使用mongodb注册所有模型的项目,并在需要访问模型的任何应用程序的app.js文件中调用init方法。

  1. 创建共享项目 - 按照标​​准流程创建新节点项目。
  2. package.json - 在共享项目中,将package.json文件设置为包含以下条目:

    "main": "index.js"
    
  3. 添加模型 - 在共享项目中创建一个新的models文件夹,以包含所有mongoose模式和插件。将您的userSchema文件添加到models文件夹并将其命名为user.js

    var mongoose = require('mongoose');
    
    var userSchema = new mongoose.Schema({
        email: String
    });
    
    module.exports = mongoose.model('User', userSchema);
    
  4. index.js - 然后在项目的根index.js文件中创建一个可供您的应用使用的共享对象,公开模型和{ {1}}方法。有很多方法可以对此进行编码,但这就是我如何做到这一点:

    init
  5. 引用您的function Common() { //empty array to hold mongoose Schemas this.models = {}; } Common.prototype.init = function(mongoose) { mongoose.connect('your mongodb connection string goes here'); require('./models/user'); //add more model references here //This is just to make referencing the models easier within your apps, so you don't have to use strings. The model name you use here must match the name you used in the schema file this.models = { user: mongoose.model('User') } } var common = new Common(); module.exports = common; 项目 - 但是,如果您想引用共享项目,请在应用内的common文件中添加对共享项目的引用,并为其指定名称package.json。我个人使用GitHub来存储项目并引用了存储库路径。由于我的存储库是私有的,我必须在路径中使用密钥,这在GitHub支持站点上有所涉及。
  6. 在您的应用中初始化模型 - 在您的应用的启动脚本中(让我们假设它为此示例common)添加引用您的app.js项目并调用common方法连接到mongodb服务器并注册模型。

    init
  7. 在应用中的任意位置使用模型 - 现在mongoose已建立连接池且模型已注册,您可以将模型用于应用中的任何类。例如,假设您有一个页面显示有关//at the top, near your other module dependencies var mongoose = require('mongoose') , common = require('common'); common.init(mongoose); 的信息,您可以这样做(未经测试的代码,只是写了一个例子):

    user
  8. 修改 对不起,我没有看到你从另一个继承一个模式的行。正如其他答案所述,mongoose已经提供了var common = require('common'); app.get('/user-profile/:id', function(req, res) { common.models.user.findById(req.params.id, function(err, user) { if (err) console.log(err.message); //do something else to handle the error else res.render('user-profile', {model: {user: user}}); }); }); 的概念。在上面的示例中,您将执行此操作:

    在您的公共模块中,' /models/base-profile-plugin.js'

    plugin

    在您的公共模块中,在/models/entrepreneur.js

    module.exports = exports = function baseProfilePlugin(schema, options){
    
        //These paths will be added to any schema that uses this plugin
        schema.add({
            _user: {type: Schema.Types.ObjectId, ref: 'User', required: true},
            name: {type: String, required: true},
            bio: {type: String, required: true},
            pictureLink: String
        });
    
        //you can also add static or instance methods or shared getter/setter handling logic here. See the plugin documentation on the mongoose website.
    }
    

答案 1 :(得分:1)

为什么不为这样的公共架构创建一个mongoose插件https://github.com/Keeguon/mongoose-behaviors/blob/master/lib/timestampable.js

答案 2 :(得分:1)

你正在寻找什么基本上是模式继承,有一个名为mongoose的项目扩展实际上解决了你的问题,你可以决定是否要实现它或者看看代码并制作你自己的

只需将其安装到npm

$ npm install mongoose-schema-extend

这是它的工作原理:

var mongoose = require('mongoose'),
    extend = require('mongoose-schema-extend');
var Schema = mongoose.Schema;

var PersonSchema = new Schema({
  name : String
}, { collection : 'users' });

var EmployeeSchema = PersonSchema.extend({
  department : String
});

var Person = mongoose.model('Person', PersonSchema),
    Employee = mongoose.model('Employee', EmployeeSchema);

var Brian = new Employee({
  name : 'Brian Kirchoff',
  department : 'Engineering'
});

问候