skip to Main Content

I’m relatively new to using Nest.js and I’m encountering an issue with implementing cascade delete functionality through pre middleware. To give you a clear example, I have two models: one related to enrollments and another related to students.

The scenario I’m dealing with is that when a student is deleted, I’d like to cascade delete all the enrollments associated with that particular student.

Student Schema:

export type StudentSchema = HydratedDocument<iStudent>;

@Schema({
   toJSON: {
      virtuals: true,
      transform: function (doc: any, ret: any) {
      delete ret._id;
      delete ret.__v;
      return ret;
    },
   },
 })

export class Student {
@Prop()
firstName: string;

@Prop()
lastName: string;

@Prop()
birthDate: Date;

@Prop()
isCustomer: boolean;

@Prop()
email: string;

@Prop()
phone: string;

@Prop({ type: mongoose.Schema.Types.ObjectId, ref: "Tutor" })
tutor: Tutor;
}

const StudentSchema = SchemaFactory.createForClass(Student);

StudentSchema.pre(["find", "findOne"],  function () {
   this.populate("tutor");
});

StudentSchema.virtual('fullname').get(function() {
   return `${this.firstName} ${this.lastName}`
});

export { StudentSchema };

In this schema, I have defined a Student class with various properties, and I’ve set up virtuals and pre middleware for population.

Enrollment Schema

export type EnrollmentSchema = HydratedDocument<iEnrollment>;

@Schema({
     toJSON: {
     virtuals: true,
     transform: function (doc: any, ret: any) {
     delete ret._id;
     delete ret.__v;
     return ret;
   },
  },
})

export class Enrollment {
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: "Student" })
student: Student;

@Prop({ type: mongoose.Schema.Types.ObjectId, ref: "Course" })
course: Course;

@Prop()
createdAt: Date;

@Prop()
status: string;
}

const EnrollmentSchema = 
SchemaFactory.createForClass(Enrollment);

EnrollmentSchema.pre(["find", "findOne"],  function () {
  this.populate('student course');
});

export { EnrollmentSchema };

In this schema, I have an Enrollment class with properties related to students, courses, and other data. I’ve also configured virtuals and pre middleware for population.

My goal is to automatically delete all the associated enrollments when a student is deleted. I’d appreciate any guidance on how to implement this cascade delete functionality using Nest.js.

Thank you in advance for your assistance! 😊

2

Answers


  1. You can cascade delete all the enrollments associated with that particular student like this example

    StudentSchema.pre(['find', 'findOne', 'remove'], async function (next) {
        const student = this;
      
        if (this.op === 'remove') {
            // Assuming 'Enrollment' is the name of your Enrollment model
            Enrollment.deleteMany({ studentId: student._id }, (err) => {
              if (err) {
                next(err);
              } else {
                next();
              }
            });
        }
      
        // Logic for pre find or findOne middleware
        // Add your own logic here if needed
        next();
    });
    
    Login or Signup to reply.
  2. You can use this post hook which will trigger whenever you use Student.findByIdAndDelete(id) and Student.findOneAndDelete({key:'value'})

    StudentSchema.post('findOneAndDelete', async (document, next)=>{
       try{
          if(document){ //< Only run if a student was found during the delete
             const deleteCascade = await Enrollment.deleteMany({student: document._id});
             console.log('Delete Count:', deleteCascade);
             next();
          }
       }catch(err){
          next(err);
       }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search