skip to Main Content

I have a one to one relationship between Users and Employees. How can i delete the user as i delete the employee related to that user and viceversa?

This is my User model:

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

const UserSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
  },
  password: {
    type: String,
    required: true,
  },
  role: {
    type: String,
    enum: ['admin', 'user'],
    default: 'user',
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

// Encrypt password using bcrypt
UserSchema.pre('save', async function (next) {
  if (!this.isModified('password')) {
    next();
  }

  const salt = await bcrypt.genSalt(10);
  this.password = await bcrypt.hash(this.password, salt);
});

// Sign JWT and return
UserSchema.methods.getSignedJwtToken = function () {
  return jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
    expiresIn: process.env.JWT_EXPIRE,
  });
};

// Match user entered password to hashed password in database
UserSchema.methods.matchPassword = async function (enteredPassword) {
  return await bcrypt.compare(enteredPassword, this.password);
};

// Cascade delete courses when a bootcamp is deleted
UserSchema.pre('remove', async function (next) {
  console.log(`Employee being removed from user ${this._id}`);
  await this.model('Employee').deleteMany({ employee: this._id });
  next();
});

const User = mongoose.model('User', UserSchema);

module.exports = User;

And this is my Employee model:

const mongoose = require('mongoose');

const employeeSchema = new mongoose.Schema({
  name: { 
    type: String, 
    required: true 
  },
  lastName: { 
    type: String, 
    required: true 
  },
  type: { 
    type: String, 
    enum: ['employee', 'manager'], 
    default: 'employee' 
  },
  createdAt: {
    type: Date,
    default: Date.now
  },
  user: {
    type: mongoose.Schema.ObjectId,
    ref: 'User',
    required: true
  }

});

const Employee = mongoose.model('Employee', employeeSchema);

module.exports = Employee;

I tried the following:

// Cascade delete courses when a bootcamp is deleted
    UserSchema.pre('remove', async function (next) {
      console.log(`Employee being removed from user ${this._id}`);
      await this.model('Employee').deleteMany({ employee: this._id });
      next();
    });

But i deleted an employee an the user was not deleted. Am i missing anything regarding the relationship?

2

Answers


  1. For User schema pre hook with the deleteOne operation

    UserSchema.pre('deleteOne', { document: true, query: false }, async function (next) {
      const user = this;
      console.log(`User being deleted: ${user._id}`);
      
      const employee = await Employee.deleteOne({ user: user._id });
      if (employee.deletedCount > 0) {
        console.log(`Associated employee deleted`);
      }
      next();
    });
    
    

    For Employee schema pre hook with the deleteOne operation

    employeeSchema.pre('deleteOne', { document: true, query: false }, async function (next) {
      const employee = this;
      console.log(`Employee being deleted: ${employee._id}`);
      
      const user = await User.deleteOne({ _id: employee.user });
      if (user.deletedCount > 0) {
        console.log(`Associated user deleted`);
      }
      next();
    });
    
    Login or Signup to reply.
  2. Schema.pre(‘remove’) is deprecated and seems not to be even working anymore.

    You need to use deleteOne, but the this is not the document here, you need to get the _id of the query

    UserSchema.pre('deleteOne', async function () {
        const _id = this.getQuery()._id;
        await mongoose.model('Employee').deleteOne({ user: _id });
    });
    
    await User.deleteOne(someId);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search