Hello I have three models
Posts:
var PostSchema = new Schema({
title: {
type: String,
required: true,
default: '',
},
content: {
type: String,
required: true,
default: '',
},
community: {
type: String,
default: '',
},
price: {
type: String,
required: true,
default: '',
},
location: {
type: String,
required: true,
default: '',
},
images: {
type:[],
required: true,
},
user: {
type: Schema.ObjectId,
required: true,
ref: 'User',
},
accepted : {
type: [],
},
comments: {
type: [Schema.Types.ObjectId],
ref:"Comment"
}
});
Users:
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
},
firstName: { type: String, required: true },
lastName: { type: String, required: true },
location: { type: String, required: true },
profilepicture: { type: String },
});
Comments
var CommentSchema = new Schema({
title: {
type: String,
default: '',
},
content: {
type: String,
default: '',
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
post: {
type: Schema.ObjectId,
ref: 'Post'
},
offer: {
type: String,
default: '',
}
});
I am trying to allow the Posts model to have an object id array of comments and for the comments to have there user objectid populated. I am using the below code for my posts route and I can get all the comments to populate but I cant get the user of the comment to populate.In theory this should work according to the mongo docs, but its not. Any ideas?
app.get('/api/posts', function(req, res) {
Post.find().populate('user comments comments.user').exec(function(err, posts) {
if (err) {
res.render('error', {
status: 500
});
} else {
res.jsonp(posts);
}
});
});
To do what you want, you would need to call populate on the inner "comments" object after the initial populate call has bee done. In a simplified version of your listing:
var async = require("async"),
mongoose = require("mongoose"),
Schema = mongoose.Schema;
mongoose.connect("mongodb://localhost/user");
var postSchema = new Schema({
title: { type: String, required: true, default: '' },
user: { type: Schema.Types.ObjectId, required: true, ref: 'User' },
comments: [{ type: Schema.Types.ObjectId, ref: "Comment" }]
});
var userSchema = new Schema({
name: String
});
var commentSchema = new Schema({
content: String,
user: { type: Schema.Types.ObjectId, ref: "User" },
post: { type: Schema.Types.ObjectId, ref: "Post" }
});
var Post = mongoose.model( "Post", postSchema );
var User = mongoose.model( "User", userSchema );
var Comment = mongoose.model( "Comment", commentSchema );
Populating the "user" on the comments would be like this:
Post.find().populate("user comments").exec(function(err,docs) {
async.forEach(docs,function(doc,callback) {
Comment.populate( doc.comments,{ "path": "user" },function(err,output) {
//console.log( "doc: " + doc );
//console.log( "proc: " + output );
callback();
});
},function(err) {
console.log( "all: " + JSON.stringify(docs,undefined,4 ));
});
});
Or however you are actually processing the results from your find on the post. The point is that your "comments" needs to be populated first and then you can call .populate()
, using the the model form, on the whole "comments" array per document in the result.