我的父级模型和子级模型require
彼此对应,所以我有cyclic dependencies。
由于循环依赖性,const Parent = require("./Parent");
并未将Parent
导入Child.js
中。因此,当我致电child.remove()
时,我得到TypeError: Parent.findById is not a function
。
他们互相引用的原因是,当删除一个孩子时,其引用ID也将从其父对象中删除。而且,当删除父对象时,我还需要从数据库中删除它的所有子对象。这些是在模式的pre hooks
中完成的在没有这种周期性依赖关系而导致错误的情况下,我该如何照顾删除孩子在其父母中的引用以及父母的孩子?
Parent.js
const mongoose = require('mongoose');
const Child = require('./Child');
const parentSchema = new mongoose.Schema(
{
name: String,
childrenIds: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'child',
},
],
},
{ timestamps: { createdAt: 'created_at' } }
);
parentSchema.pre('remove', async function (next) {
await Child.deleteMany({ _id: { $in: this.childrenIds } });
next();
});
const Parent = mongoose.model('Parent', parentSchema);
module.exports = Parent;
Child.js:
const mongoose = require('mongoose');
const Child = require('./Child');
const parentSchema = new mongoose.Schema(
{
name: String,
childrenIds: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'child',
},
],
},
{ timestamps: { createdAt: 'created_at' } }
);
parentSchema.pre('remove', async function (next) {
await Child.deleteMany({ _id: { $in: this.childrenIds } });
next();
});
const Parent = mongoose.model('Parent', parentSchema);
module.exports = Parent;
app.js:
const Parent = require('./models/Parent');
const Child = require('./models/Child');
const mongoose = require('mongoose');
mongoose
.connect('mongodb://localhost/circularDep_db', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: true,
})
.then(() => console.log('Successfully connect to MongoDB.'))
.catch((err) => console.error('Connection error', err));
const addChild = async (parent, child) => {
child.parentId = parent._id;
await child.save();
parent.childrenIds.push(child);
await parent.save();
};
async function run() {
const parent = await Parent.create({ name: 'Caryn' });
const child = await Child.create({ name: 'Dashie' });
const child2 = await Child.create({ name: 'Chappie' });
await addChild(parent, child);
await addChild(parent, child2);
await child.remove(); // throws a type error
await parent.remove();
}
run();