60

This is my folder structure:

+-- express_example
|---- app.js
|---- models
|-------- songs.js
|-------- albums.js
|---- and another files of expressjs

My code in file songs.js

var mongoose = require('mongoose')
, Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;

var SongSchema = new Schema({
name: {type: String, default: 'songname'}
, link: {type: String, default: './data/train.mp3'}
, date: {type: Date, default: Date.now()}
, position: {type: Number, default: 0}
, weekOnChart: {type: Number, default: 0}
, listend: {type: Number, default: 0}
});

module.exports = mongoose.model('Song', SongSchema);

And here is my code in file albums.js

var mongoose = require('mongoose')
, Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;

var AlbumSchema = new Schema({
name: {type: String, default: 'songname'}
, thumbnail: {type:String, default: './images/U1.jpg'}
, date: {type: Date, default: Date.now()}
, songs: [SongSchema]
});

module.exports = mongoose.model('Album', AlbumSchema);


How can I make albums.js know SongSchema to be defined AlbumSchema

Community
  • 1
  • 1
Huy Tran
  • 4,371
  • 10
  • 34
  • 38

5 Answers5

106

You can get models defined elsewhere directly with Mongoose:

require('mongoose').model(name_of_model)

To get the schema in your example in albums.js you can do this:

var SongSchema = require('mongoose').model('Song').schema
tronman
  • 9,862
  • 10
  • 46
  • 61
alessioalex
  • 62,577
  • 16
  • 155
  • 122
  • If with my database structure like that, then 1 album i can store many song, is that right?
    And why in app.js do:
    `var Album = db.model('Album'); var album = new Album(); album.songs.push({_id:'4f046b3bf71f5ed522000002'});`
    and I get error `Cannot call method 'call' of undefined`
    how do i store to right?
    – Huy Tran Jan 04 '12 at 17:20
  • 11
    I was getting the exact same thing. Ended up fixing it by using `var SongSchema = require('mongoose').model('Song').schema` instead (i.e. I added `.schema` to grab the schema of the model specifically). – jangosteve Jul 17 '12 at 04:38
  • So how does this work when there are multiple connections? Which one does it use? – bryanph Aug 09 '16 at 10:02
28

To get the schema from a registered Mongoose model, you need to access the schema specifically:

var SongSchema = require('mongoose').model('Song').schema;
peteallen
  • 2,553
  • 2
  • 17
  • 16
6

For others not as familiar with the deeper aspects of how Mongoose works, the existing answers can be confusing.

Here's a generalized implementation example of importing a schema from another file that is accessible to a wider audience coming from a more general context.

const modelSchema = require('./model.js').model('Model').schema

Here's a modified version for the specific case in the question (this would be used inside albums.js).

const SongSchema = require('./songs.js').model('Song').schema

From this, I can see that you first access and require the file how one would normally go about requiring a model, except in this case you now specifically access the schema of that model.

Other answers require mongoose within the variable declaration and that goes against the commonly found example of requiring mongoose before through declaring a variable such as const mongoose = require('mongoose'); and then using mongoose like that. Such a use case was not accessible knowledge-wise to me.


Alternative option

You can require just the model like you normally would and then refer to the schema through the Model's schema property.

const mongoose = require('mongoose');

// bring in Song model
const Song = require('./songs.js');

const AlbumSchema = new Schema({
    // access built in schema property of a model
    songs: [Song.schema]
});
danefondo
  • 525
  • 7
  • 15
3
var SongSchema = require('mongoose').model('Song').schema;

The above line of code in your albums.js will surely work.

Amol M Kulkarni
  • 21,143
  • 34
  • 120
  • 164
0
"songs" : [{type: Schema.Types.ObjectId, ref: 'Song', required: true}]
danH
  • 105
  • 10