Saurabh Gupta
Saurabh Gupta

Reputation: 81

How to implement cascade insert with MEAN/MongoDB?

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

Answers (2)

chrisbajorin
chrisbajorin

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

scuencag
scuencag

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

Related Questions