I have 3 schemas, 2 of which have a .pre('save')
hook to push its _id
into the previous one's. You can take the example of a forum with topics, questions and comments
var topicSchema = new Schema({
arr: {type:[Schema.ObjectId], ref:'Question'},
});
var Topic = new mongoose.model('Topic', topicSchema);
var questionSchema = new Schema({
targetId: {type:Schema.ObjectId, ref:'Topic', required:true},
arr: {type:[Schema.ObjectId], ref:'Comment'},
});
var Question = new mongoose.model('Question', questionSchema);
var commentSchema = new Schema({
targetId: {type:Schema.ObjectId, ref:'Question', required:true},
});
var Comment = new mongoose.model('Comment', commentSchema);
Now for the above schema I want: When I save a question I want to automatically push the question's _id
to its respective Topic.arr
and when I save a comment to auto push its it to its respective Question.arr
I've tried solving this using .pre('save')
hooks as follows:
function addPreSave (schema, idProperty, containerProperty) {
var modelName = schema.paths[idProperty].options.ref;
var model = mongoose.models[modelName];
schema.pre('save', function (next) {
model.findById(this[idProperty], function (err, doc) {
doc[containerProperty].push(this._id);
doc.save(next);
}.bind(this));
});
}
addPreSave(questionSchema, 'targetId', 'arr');
addPreSave(commentSchema, 'targetId', 'arr');
All that the above function does (and the 2 calls to it) is to add a .pre('save')
hook to each of the 2 schemas to add their _id
in their respective parent.
THE ISSUE: The problem is that now, every time I save a comment, it pushes its id to the topic, but I only actually want to do this the very first time only. So in the above example if you create a topic, then a question for it and then a comment for the question, the Topic.arr
will have 2 ids in it (twice the question's _id
) as it saves once for the question and a second time it's triggered by the comment's call to save the question
Does anyone know a way around this, or more specifically if you know how to figure out in the pre-save hook if this is a first-time save or not?
To get the object ID after an object is saved in Mongoose, we can get the value from the callback that's run after we call save . const { Schema } = require('mongoose') mongoose. connect('mongodb://localhost/lol', (err) => { if (err) { console. log(err) } }); const ChatSchema = new Schema({ name: String }); mongoose.
The __v field is called the version key. It describes the internal revision of a document.
The versionKey is a property set on each document when first created by Mongoose. This keys value contains the internal revision of the document. The name of this document property is configurable.
ObjectId . A SchemaType is just a configuration object for Mongoose. An instance of the mongoose. ObjectId SchemaType doesn't actually create MongoDB ObjectIds, it is just a configuration for a path in a schema.
So it turns out that you can find the answer to anything if you are willing to go on the second page of Google!
There is a property defined for every document called isNew which does what you might imagine. So just adding a if (!this.isNew) return next()
in the method fixes the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With