Ian
Ian

Reputation: 345

How to seed dependent data in Node/MongoDB

I am trying to seed a MongoDB database with a one-to-many relationship using objectID's. Something like the following:

var postSchema = mongoose.Schema({
  name: {type: String, required: true, unique: true},
  description: {type: String},
  userlikes: [{type: mongoose.Schema.Types.ObjectId, ref: 'Users'}]
});

A synchronous implementation of this would look something like this (pseudocode):

openConnection()
cleardb()
users = createUsers()  
post = createPost(users)

Using Node I need to nest each of these calls which gets messy and makes re-use of objects difficult (I may want to create further dependent objects after). I have had a look at async but that doesn't appear to help too much in this case - I could use async.waterfall but that would give me something similar to the nested solution only flattened into an array.

When seeding related data it obviously helps if you can create data objects and then assume they exist for building subsequent data structures. Obviously this doesn't really happen with an asynchronous approach. Am I missing the point here?

I would assume that with node used so extensively for API's this would be a common challenge for setting up data for testing but I can't find an elegant solution documented anywhere.

Can anyone point me to an example implementation of how this problem is solved in a node setup?

Upvotes: 2

Views: 3071

Answers (1)

CHAPa
CHAPa

Reputation: 677

using async could be very handy.
all business logic/task in the end of the day is just a sequence of operations. waterfall is an abstraction very useful to your solution.

for instance: seed.js

var User = require('../path/to/your/models/User');
var Post = require('../path/to/your/models/Post');
var DB   = require('../path/to/your/database/boot/module');
var config = require('../path/to/your/configuration');

function startDB(config, callback) {
  DB.start(config, callback);
}

function createUsers(userParams, callback) {
  User.save(userParams, callback); 
}

function createPost(users, callback) {
  Post.save(users, callback);
}

function resolvedCallback(err, posts) {
  if (err)
    return your-error-handling-here;

  console.log(posts);
  DB.cleanup(console.log.bind(null, 'clean up finished: '));
}

async.waterfall([
  async.constant({ db: config.dbOpts}),
  startDB, // we don't need the wrapper, we could use DB.start
  createUsers,
  createPost ], resolvedCallback);

If you are using some test framework (mocha/tape), you could initialize the database before all your tests and cleanup before start/after all tests.

cheers

Upvotes: 1

Related Questions