gpt4 book ai didi

Mongoose Model wont fire pre("remove") hook(Mongoose模型不会发射预挂(“移除”)挂钩)

转载 作者:bug小助手 更新时间:2023-10-24 22:22:44 29 4
gpt4 key购买 nike



I am trying to create a cascading delete hook. When the user is removed from mongo, I want associated records to be removed as well. I can do this from within the code and with separate calls, however I am trying to use the pre remove hook. The primary record was removed as expected however none of the actions in the pre hook were activated.

我正在尝试创建级联删除挂钩。当用户从Mongo中删除时,我希望关联的记录也被删除。我可以在代码中使用单独的调用来完成此操作,但是我正在尝试使用Pre Remove挂钩。主记录已按预期删除,但是预挂接中的任何操作都未激活。


Environment: Mongoose 7.50, Nodejs 18+

环境:Mongoose 7.50,NodeJS 18+


Here is the code in the main application to trigger the removal of the user.

下面是主应用程序中触发删除用户的代码。


    const user = User.findById(req.user._id).select("_id");
await user.deleteOne();

Here is the relevant section of the user model.

以下是用户模型的相关部分。


// These functions act on the schema

// Encrypt password using bcrypt
schema.pre("save", async function (next) {
if (!this.isModified("password")) {
next();
}
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
});

schema.pre("remove", async function (next) {
// get the string value of user._id because the other tables don't use the obj id of userid.
const userId = this._id.toString();
console.log("🚀 ~ file: user.js:155 ~ userId:", userId);

console.log("we are in cascade delete");

// remove the messages from the messages table and that will cascade to the messageswaiting table.
await this.model("message").deleteMany({ user_id: userId });

// remove the archive messages from the archive table.
await this.model("archive").deleteMany({ user_id: userId });

// freeze the username for 30 days.
const frozen = new this.model("frozenusername")({ username: this.username });
await frozen.save();
next();
});

The console.log entries do not appear in the logs. which seem to tell me that the hook is not firing. I am not sure where to turn. The mongoose website doesn't seem to talk about the remove hook. The code doesn't error out in any way. It happily deletes the user account, just non of the related documents.

Console.log条目不会出现在日志中。这似乎是在告诉我,鱼钩并没有开火。我不知道该往哪里拐。Mongoose网站似乎没有谈论Remove钩子。代码不会以任何方式出错。它愉快地删除了用户帐户,只是不删除相关文档。


Thank you for your help.

谢谢你的帮助。


更多回答

i am not sure how user.deleteOne() will be a success without awaiting the User.findById(). Your are positive that user is being deleted?

我不知道如何用户.deleteOne()将是一个成功的,而不等待用户.findById()。您确定用户正在被删除吗?

that is a good catch, I didn't even see that. I will try it.

这是一个很好的接球,我甚至都没有看到。我要试一试。

does the name of the pre hook, in my case "remove" have to match the deleteOne? so should the hook become pre("deleteOne" ?

前钩子的名称,在我的例子中是“Remove”,是否必须与DeleteOne匹配?那么,钩子是否应该变为pre(“deleteOne”?

优秀答案推荐

We can use the query await User.deleteOne({_id: _id}) This is called a model query. When you execute this query, the actual document data is NOT available inside the model. So you have to first create a document, then act on the document. This way when you are doing cascading deletes you have access to the parent _id via this._id object. So first you start with:

我们可以使用查询等待User.deleteOne({_id:_id}),这称为模型查询。当您执行此查询时,实际的文档数据在模型中不可用。因此,您必须首先创建一个文档,然后对该文档执行操作。这样,当您执行级联删除时,您可以通过这个._id对象访问parent_id。因此,首先要从以下几个方面入手:


// remove all db data. This is cascading.
const delUser = await User.findById(req.user._id).exec();
await delUser.deleteOne();

Inside the User model there are a few things you need to do. First you need to include or require the models you are going to act on.

在用户模型中,您需要做一些事情。首先,您需要包括或要求您将要采取行动的模型。


const Message = require("./message");
const Archive = require("./archive");
const Frozen = require("./frozen_username");

Next when you define your pre hook, the name of the hook has to match the query, in this case deleteOne. BTW not all model and document types are available as a hook. See here: Mongoose Docs

接下来,当您定义预挂接时,挂接的名称必须与查询匹配,在本例中为deleteOne。顺便说一句,并不是所有的模型和文档类型都可以作为挂钩。请看这里:猫鼬文档


so here is the pre hook defined:

下面是定义的前挂钩:


schema.pre("deleteOne", { document: true, query: false }, async function (next) {
// get the string value of user._id because the other tables don't use the obj id of userid.
let userId = this._id;
userId = userId.toString();
// remove the messages from the messages table
await Message.deleteMany({ user_id: userId });
// remove the archive messages from the archive table.
await Archive.deleteMany({ user_id: userId });
// freeze the username for 30 days.
await Frozen.create({ username: this.username });
});

You will notice this part { document: true, query: false }, Here deleteOne can be a document or a query. In this special hook you need to tell it which you are using.

您会注意到这一部分:{Document:True,Query:False},在这里删除一个可以是文档也可以是查询。在这个特殊的钩子中,您需要告诉它您正在使用哪个钩子。


更多回答

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com