Mongoose populate after save
I cannot manually or automatically populate the creator field on a newly saved object ... the only way I can find is to re-query for the objects I already have which I would hate to do.
This is the setup:
var userSchema = new mongoose.Schema({
name: String,
});
var User = db.model('User', userSchema);
var bookSchema = new mongoose.Schema({
_creator: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
description: String,
});
var Book = db.model('Book', bookSchema);
This is where I am pulling my hair
var user = new User();
user.save(function(err) {
var book = new Book({
_creator: user,
});
book.save(function(err){
console.log(book._creator); // is just an object id
book._creator = user; // still only attaches the object id due to Mongoose magic
console.log(book._creator); // Again: is just an object id
// I really want book._creator to be a user without having to go back to the db ... any suggestions?
});
});
EDIT: latest mongoose fixed this issue and added populate functionality, see the new accepted answer.
You should be able to use the Model's populate function to do this: http://mongoosejs.com/docs/api.html#model_Model.populate In the save handler for book, instead of:
book._creator = user;
you'd do something like:
Book.populate(book, {path:"_creator"}, function(err, book) { ... });
Probably too late an answer to help you, but I was stuck on this recently, and it might be useful for others.
The solution for me was to use execPopulate
, like so
const t = new MyModel(value)
return t.save().then(t => t.populate('my-path').execPopulate())
In case that anyone is still looking for this.
Mongoose 3.6 has introduced a lot of cool features to populate:
book.populate('_creator', function(err) {
console.log(book._creator);
});
or:
Book.populate(book, '_creator', function(err) {
console.log(book._creator);
});
see more at: https://github.com/LearnBoost/mongoose/wiki/3.6-Release-Notes#population
But this way you would still query for the user again.
A little trick to accomplish it without extra queries would be:
book = book.toObject();
book._creator = user;
The solution which returns a promise (no callbacks):
Use Document#populate
book.populate('creator').execPopulate();
// summary
doc.populate(options); // not executed
doc.populate(options).execPopulate() // executed, returns promise
Possible Implementation
var populatedDoc = doc.populate(options).execPopulate();
populatedDoc.then(doc => {
...
});
Read about document population here.