外部模块中的架构在Node.js中不起作用 [英] Schemas in external module not working in Node.js

查看:53
本文介绍了外部模块中的架构在Node.js中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我非常想通过一个模块与我代码库中的所有其他模块共享一些通用的架构定义.

I'm having a massive headache try to share some common schema definitions via a module to all the other modules in my code base.

我有一个myproj_schemas模块,其中包含以下两种模式:

I have a myproj_schemas module that contains these two 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;

导师也定义在另一个文件中.

Mentors is also defined in another file.

我的单元测试都可以在schemas模块中完成这两项工作.

My unit tests for these both work in the schemas module.

当我npm安装此模块并尝试使用创建时

When I npm install this module and try to create using

Entrepreneur = db.model('Entrepreneur', entrepreneurSchema),

我收到以下错误:

TypeError:paths.mentors处的类型不确定 您是否尝试过嵌套架构?您只能使用引用或数组进行嵌套.

TypeError: Undefined type at paths.mentors Did you try nesting Schemas? You can only nest using refs or arrays.

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

If I use the same code in my local module, then no problem. If I reference the schema file directly in the require (e.g. require('../node_modules/myproj_schemas/models/ent_schema') then I get the error.

我相当确定它不会像以前那样中断,但是我已经撤消了所有更改,但仍然无法正常工作.

I'm fairly sure it wasn't breaking like this earlier, but I've backed out all the changes and it is still not working.

我正在绘制一个完整的空白,将不胜感激地收到任何建议.

I'm drawing a complete blank, and any suggestions would be gratefully received.

我创建了一个新的Schemas模块.它具有一个模式:

I've created a new Schemas module. It has one Schema:

var mongoose = require('mongoose');

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

module.exports = userSchema;

当打包到一个模块中并且将npm安装到其他模块时,这也会失败.

This also fails when packaged up in a module and npm install'd to other modules.

在OS X上运行

推荐答案

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

Personally I created separate "common" project with an init method to register all of the models with mongodb, and call the init method in the app.js file of any apps that need access to the models.

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

  1. Create a shared project - Create a new node project, following the standard process.
  2. package.json - In the shared project, set your package.json file to contain the following entry:

"main": "index.js"

  • 添加模型-在共享项目中创建一个新的models文件夹,其中包含所有猫鼬模式和插件.将您的userSchema文件添加到models文件夹并将其命名为user.js.

  • Add a model - Create a new models folder within your shared project, to contain all of your mongoose schemas and plugins. Add your userSchema file to the models folder and name it user.js.

    var mongoose = require('mongoose');
    
    var userSchema = new mongoose.Schema({
        email: String
    });
    
    module.exports = mongoose.model('User', userSchema);
    

  • index.js -然后在项目的根index.js文件中创建一个共享对象,供您的应用使用,公开模型和init方法.有很多方法可以对此进行编码,但是这是我的操作方式:

  • index.js - Then in the project's root index.js file create a shared object that can be used by your apps, exposing the models and an init method. There's many ways to code this, but here's how I'm doing it:

    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支持站点上涵盖.
  • 在您的应用程序中初始化模型-在您的应用程序的启动脚本中(假设此示例为app.js),将引用添加到您的common项目并调用init方法连接到mongodb服务器并注册模型.

  • Reference your common project - However you want to reference your shared project, add the reference to the shared project in the package.json file within your app and give it a name of common. Personally I used GitHub to store the project and referenced the repository path. Since my repository was private I had to use a key in the path, which is covered on the GitHub support site.
  • Init the models in your app - In the start script for your app (let's assume it's app.js for this example) add the reference to your common project and call the init method to connect to the mongodb server and register the models.

    //at the top, near your other module dependencies
    var mongoose = require('mongoose')
      , common = require('common');
    
    common.init(mongoose);
    

  • 在应用程序中的任何位置使用模型-既然mongoose已经建立了连接池并且已经注册了模型,则可以使用模型中的任何模型.例如,假设您有一个页面显示有关user的信息,则可以这样操作(未经测试的代码,仅为示例编写):

  • Use the model anywhere in your app - Now that mongoose has the connection pool established and the models have been registered, you can use the models is any of the classes within your app. For example, say you have a page that displays information about a user you could do it like this (untested code, just wrote this for an example):

    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}});
        });
    });
    

  • 编辑 抱歉,我没有看到您从另一个继承一个架构的那一行.正如其他答案之一所述,猫鼬已经提供了plugin的概念.在上面的示例中,您将执行以下操作:

    EDIT Sorry, I didn't see the line where you were inheriting one schema from another. As one of the other answers stated, mongoose already offers the concept of a plugin. In your example above, you would do this:

    在您的通用模块中的"/models/base-profile-plugin.js"下

    In your common module, under '/models/base-profile-plugin.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.
    }
    

    在您的通用模块的'/models/entrepreneur.js

    In your common module, under '/models/entrepreneur.js

    var mongoose    = require('mongoose')
      , basePlugin  = require('./base-profile-plugin.js');
    
    var entrepreneurSchema   = new mongoose.Schema({
        mentors: {type: Schema.Types.ObjectId, ref: 'Mentor'}
    });
    
    entrepreneurSchema.plugin(basePlugin);
    
    module.exports = mongoose.model('Entrepreneur', entrepreneurSchema);
    

    这篇关于外部模块中的架构在Node.js中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆