mongoose 如何删除一对一关系中的级联?

jgzswidk  于 2023-06-23  发布在  Go
关注(0)|答案(2)|浏览(139)

我在用户和员工之间建立了一对一的关系。如何在删除与该用户相关的员工时删除该用户,反之亦然?
这是我的用户模型:

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;

这是我的员工模型:

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;

我尝试了以下操作:

// 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();
    });

这是我的控制器中的deleteUser方法:

exports.deleteUser = asyncHandler(async (req, res, next) => {
  // Ensure the request has a user object populated by the protect middleware
  if (!req.user) {
    return next(new ErrorResponse('Not authorized to delete this user', 401));
  }

  const user = await User.findById(req.params.id);
  if (!user) {
    return next(
      new ErrorResponse(`User not found with id of ${req.params.id}`, 404)
    );
  }

user.deleteOne();

  res.status(200).json({
    success: true,
    data: {},
  });
});

但是我删除了一个员工,用户没有被删除。我错过了什么关于关系吗?

1szpjjfi

1szpjjfi1#

对于User schema使用deleteOne操作的pre钩子

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();
});

对于Employee schema使用deleteOne操作的pre钩子

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();
});
gkn4icbw

gkn4icbw2#

你可能在其他地方遇到了问题,你的代码应该工作得很好,这是一个单文件工作示例,当它运行时,它会打印用户的id以便删除,只需点击带有id的端点
http://localhost:3000/delete/_id_here

const express = require("express");
const app = express();

const mongoose = require('mongoose');
mongoose.set('strictQuery', true);

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,
    },
});

UserSchema.pre('deleteOne', { document: true }, async function () {
    console.log(`User to delete: ${this._id}`);

    const employee = await Employee.deleteOne({ user: this._id });
    if (employee.deletedCount > 0) {
        console.log(`Linked employee also deleted`);
    }
});

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

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);

(async function ConectToDBAndPrepareData() {
    await mongoose.connect("mongodb://user:password@0.0.0.0:50000", { dbName: "" });

    await Employee.deleteMany();
    await User.deleteMany();

    const userToDelete = await User.create({ role: "admin", email: "will be deleted", password: "pass1" });
    const userToKeep = await User.create({ role: "admin", email: "will keep", password: "pass2" });
    await Employee.create({ name: "will be deleted", user: userToDelete._id, lastName: "aadsa" });
    await Employee.create({ name: "will keep", user: userToKeep._id, lastName: "aadsa" });

    console.log("delete this:", userToDelete._id.toString());
})();

app.get("/delete/:id", async (req, res, next) => {
    const user = await User.findById(req.params.id);
    if (!user) {
        return next(
            new ErrorResponse(`User not found with id of ${req.params.id}`, 404)
        );
    }

    user.deleteOne();

    res.status(200).json({
        success: true,
        data: {},
    });
});

const PORT = 3000;
app.listen(PORT, function (err) {
    if (err) console.log(err);
    console.log("Server listening on PORT", PORT);
});

相关问题