10
\$\begingroup\$

I'm using mongoose to seed a mongodb database based on my mongoose models. I'm particular interested in improving the seed code.

I have two models, an article and a category. The relationship between the models are as follows:

A category has many articles An article has a parent category

The model schemas I'm using are listed below:

The category schema

var mongoose = require('mongoose');

var categorySchema = mongoose.Schema({
    title: String,
    articles : [{ type: mongoose.Schema.Types.ObjectId, ref: 'Article' }]
});

mongoose.model('Category', categorySchema);

The article schema

var mongoose = require('mongoose');

var articleSchema = mongoose.Schema({
    category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' },
    title: String
});

mongoose.model('Article', articleSchema);

I'm using the following code to seed:

Seeding the category

var CategoryModel = require('mongoose').model('Category');

exports.seedCategories = function seedCategories() {
    CategoryModel.find({}).exec(function (err, collection) {
        if (collection.length === 0) {
            CategoryModel.create({ title: 'Category One' });
            CategoryModel.create({ title: 'Category Two' });
        }
    });
}

Seeding the article

var CategoryModel = require('mongoose').model('Category');
var ArticleModel = require('mongoose').model('Article');

exports.seedArticles = function seedArticles() {

    ArticleModel.find({}).exec(function (err, collection) {
        if (collection.length === 0) {
            seedArticle('Category One', 'Article One');
            seedArticle('Category One', 'Article Two');
            seedArticle('Category Two', 'Article Three');
            seedArticle('Category Two', 'Article Four');
        }
    });

    function seedArticle(categoryTitle, articleTitle) {
        var parentCategory;
        CategoryModel.findOne({ title: categoryTitle }).exec()
            .then(function (category) {
                parentCategory = category;
                return ArticleModel.create({ title: articleTitle, _category: parentCategory._id });
            }).then(function (article) {
                parentCategory.articles.push(article._id);
                parentCategory.save(function (saveError) {
                    if (!saveError) {
                        console.log("Seeded article");
                    } else {
                        console.log(saveError);
                    }
                });
            });
    }
}

I'm particularly interested in methods for preventing the Christmas tree of doom, and removing the obstruent error handling. Any recommendations are welcome, and thanks in advance for the help. I hope this code helps others.

Mongoose have just implemented promises returned from saves, so that should help. It will be available in mongoose 3.10.

\$\endgroup\$
4
\$\begingroup\$

It seems that you are storing the data with double links (article -> category AND category -> articles).

I assume that you need to report on articles for a category. I would simple create an index on Category like this:

var articleSchema = mongoose.Schema({
    category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category', index: true },
    title: String
});

This way you can simplify your code a ton by keeping it KISS:

function seedArticle(categoryTitle, articleTitle) {
  CategoryModel.findOne({ title: categoryTitle }).exec()
    .then(function (category) {
      return ArticleModel.create({ title: articleTitle, category: category._id });
    });
}

Other than that, I like your code.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your input. My reason for maintaining both links is the ability to use mongoose populate from the parent. But your suggestion is appealing as the code is tidier. Any other recommendations or pointers on how to achieve this are most welcome. Thanks again. \$\endgroup\$ – Gerard Downes Feb 20 '14 at 0:02
  • \$\begingroup\$ what is the name and where is the file stored,? I am asking this regarding the second code snippet. \$\endgroup\$ – inquisitive Apr 16 '15 at 13:28
  • \$\begingroup\$ I too would like to know where/in which file is this code stored so node executes it and takes advantage of the mongoose schemas that are already in the models folder. \$\endgroup\$ – LaserBeak Sep 24 '15 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.