Reputation: 81
I'm trying to implement cascade insert for objects with 1 to many relationship in Mongoose/MongoDB and struggling to implement it. In this case, university has one to many relationship with departments. Here is my university object.
var UniversitySchema = new Schema({
name: {
type: String,
default: '',
trim: true
},
departments: [{
type: Schema.ObjectId,
ref: 'Department'
}]
});
mongoose.model('University', UniversitySchema);
Here is my department schema:
var DepartmentSchema = new Schema({
name: {
type: String,
default: '',
trim: true
},
University: {
type: Schema.ObjectId,
ref: 'University'
}]
});
mongoose.model('Department', DepartmentSchema);
Here is what I tried putting inside post in the schema. Basically when I save a department, I'm trying to insert department Id in the university to establish one to many relationship in both direction. Of course, I'm also saving university ID while creating department - which is pretty easy.
DepartmentSchema.post('save', function(next) {
var university = University.find({_id: this.university._id});
if(!university.departments) {
university.departments = [];
}
university.departments.push(new ObjectId(this._id));
university.save().exec();
next();
});
This gives error on this line, saying it can't recognize save method on university object.
university.save().exec();
I've also tried doing this inside model server controller, but that doesn't seem right as most methods are wrapped by REST request. Of course, I can handle this from client side by making multiple requests, but I suppose there is a way to do this on server side. Since this is very internal to data layer, in my opinion, I should be able to handle this using mongo middleware.
Upvotes: 0
Views: 1805
Reputation: 6153
The result of queries get passed to callbacks, not returned.
var university = University.findOne({_id: this.university._id});
The variable university
is now a query object, not the result of the query. This is why you get TypeError: Object# < Query > has no method 'save'
. Results from queries are passed to the callback function of the query:
University.findOne({_id: this.university._id}, function(err, university){
// here is your result
});
Similarly, you need to pass the final callback into your save:
university.save(next)
Upvotes: 2
Reputation: 664
The save method must have the callback function parameter, try this:
university.save(function (err) {
if (err) return handleError(err);
// saved!
})
Upvotes: 1