1

I am trying to build a simple blog, where are posts and categories. Articles can be currently added to a parent category (in the future, they might be added to multiple categories). A category has many articles. This is what I came up with:

Category.js:

const CategorySchema = new Schema({
    name: {
        type: String,
        required: true,
        trim: true
    },
    user: { // I wanted to know what user created the category
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'User'
    }
},
{
    timestamps: true
});

const Category = mongoose.model('categories', CategorySchema);
module.exports = Category;

Article.js:

const ArticleSchema = new Schema({
    name: {
        type: String,
        required: true,
        trim: true
    },
    article_body: {
        type: String,
        trim: true
    },
    userId: { 
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'User'
    },
    categoryId: { 
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'Category'
    }
},
{
    timestamps: true
});

const Article = mongoose.model('articles', ArticleSchema);

module.exports = Article;

When I try to load articles with their category names/details:

Article.find({}).populate('categoryId').sort('name').exec(function(err, articles) {
            if(err) throw err;
            res.send(JSON.stringify(articles));
        });

I get this error:

MissingSchemaError: Schema hasn't been registered for model "Category".
Use mongoose.model(name, schema)

I am new to NoSQL, so I am not even sure if this model structure is appropriate for my case (if it would not be simply better to use sub/embedded document). The data (articles) would be read by visitors and visitors can filter articles by categories.

user2932090
  • 331
  • 2
  • 7
  • 16
  • Could you please try adding `module.exports = Category;` in the end of your `Category.js` file. – Brijesh Shah Sep 08 '18 at 19:39
  • 2
    Why do you did this: `const Article = mongoose.model('articles', EventSchema);` instead of `const Article = mongoose.model('articles', ArticleSchema);`? And you can try do `ref: 'categories'`. – BrTkCa Sep 08 '18 at 19:56
  • @BrijeshShah it's there, a mistake while copying the code. – user2932090 Sep 08 '18 at 21:29
  • @LucasCosta a mistake while copying the code, corrected. When I try to add `ref: 'categories`, I get this error (from the JSX code): `Objects are not valid as a React child (found: object with keys {_id, name, createdAt, updatedAt, __v}). If you meant to render a collection of children, use an array instead.` – user2932090 Sep 08 '18 at 21:33
  • [I was able to solve this problem by following this answer: https://stackoverflow.com/questions/18001478/referencing-another-schema-in-mongoose](https://stackoverflow.com/questions/18001478/referencing-another-schema-in-mongoose) – user2932090 Sep 09 '18 at 23:42

1 Answers1

4
const Category = mongoose.model('categories', CategorySchema);

Above line says mongoose that the model you are declaring has the name categories

categoryId: { 
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'Category' // this name does not match to 'categories'
}

Here you are saying categoryId is referencing to Category model!

So the issue is in your model name declaration. You should use same name in both lines.

Vishnu Singh
  • 431
  • 4
  • 13
  • Hi @hvish, thank you for your answer. If I change the line `const Category = mongoose.model('categories', CategorySchema);` to `const Category = mongoose.model('Category', CategorySchema);`and load the data (`Article({}).populate('Category').sort('name').exec(function(err, events) {...`), nothing happens. I am trying to print out the category name as `{article.categoryId ? article.categoryId.name : 'no category' }`. – user2932090 Sep 09 '18 at 20:27