Plug-in schemas do not work in Node.js

I have a massive headache to share some common schema definitions with a module to all other modules in my code base.

I have a module myproj_schemas that contains these two schemes:

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; 

and

 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 are also defined in another file.

My unit tests for both of these work in the circuit module.

When I install this module and try to create using

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

I get the following error:

TypeError: Undefined enter paths.mentors Have you tried paths.mentors schema? You can only embed with links or arrays.

If I use the same code in my local module, then there is no problem. If I refer to the schema file directly in require (for example, require ('../node_modules/myproj_schemas/models/ent_schema'), then I get an error.

I am sure that this did not break before, but I canceled all the changes and still does not work.

I draw a complete space, and any suggestions would be greatly appreciated.

EDIT:

I created a new Schemas module. It has one circuit:

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

It also fails to pack in a module and npm install'd to other modules.

Work on OS X

+7
mongodb mongoose
source share
3 answers

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

  • Create a shared project . Create a new node project following standard processes.
  • package.json . In a general project, set the following entry for your package.json file:

     "main": "index.js" 
  • Add model . Create a new models folder as part of your overall project to contain all of your mongoose schemas and plugins. Add the 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 . Then, in the root file of the index.js project index.js create a shared object that can be used by your applications by exposing models and the init method. There are many ways to code this, but here is how I do 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; 
  • Link to the common project . However, if you want to link to your shared project, add the link to the shared project to the package.json file in your application and give it the name common . Personally, I used GitHub to store the project and reference the repository path. Since my repository was closed, I had to use the key in the path that is described on the GitHub support site.
  • Initiate models in your application . At the beginning of the script for your application (suppose this is app.js for this example) add a link to the 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); 
  • Use the model anywhere in your application . Now that mongoose has a connection pool and models are registered, you can use models of any of the classes in your application. For example, let's say you have a page that displays information about user , you can do it like this (unverified 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}}); }); }); 

EDIT Sorry, I did not see the line where you inherited one scheme from another. As one of the other answers said, mongoose already offers a plugin concept. In the above example, you will do the following:

In your general 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. } 

In your general 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); 
+6
source share

Why don't you create a mongoose plugin for a generic scheme like https://github.com/Keeguon/mongoose-behaviors/blob/master/lib/timestampable.js

+1
source share

what you are looking for mainly to inherit the scheme, there is a project called mongoose that practically solves your problem, you can either decide whether you want to implement it, or take a look at the code and make your own.

just install it usng npm

 $ npm install mongoose-schema-extend 

this is how it works:

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

considers

+1
source share

All Articles