De acuerdo con los documentos de mongoose, hay 3 formas de agregar métodos personalizados a sus documentos:
Sin embargo, después de muchos intentos, solo he logrado que los métodos funcionen con la opción 1. Tengo curiosidad por saber por qué las opciones 2 y 3 no funcionan para mí. aquí está mi código:
aplicación.js
socket.on("message", async function (clusterData, callback) {
console.log("socket event fired");
const parentCluster = await Message.findById(clusterData.clusterId);
coonsole.log(parentCluster); // exists as expected
parentCluster.optionsMethod(); // log : "options method called" ✔
parentCluster.objectMethod(); // error : parentCluster.objectMethod is not a function ❌
parentCluster.helperMethod(); // error : parentCluster.helperMethod is not a function ❌
});
Mensaje.js
import mongoose from "mongoose";
const messageSchema = new mongoose.Schema({
mentions: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
text: { type: String, trim: true },
file: { type: String },
dateString: { type: String, required: true },
timestamp: { type: Number, required: true },
});
const messageClusterSchema = new mongoose.Schema(
{
sender: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
channel: {
type: mongoose.Schema.Types.ObjectId,
ref: "Channel",
required: true,
},
group: {
type: mongoose.Schema.Types.ObjectId,
ref: "Group",
required: true,
},
content: [messageSchema],
clusterTimestamp: {
type: Number,
required: true,
},
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true },
methods: {
optionsMethod() {
console.log("options method called");
},
},
}
);
messageClusterSchema.virtual("lastMessage").get(function () {
return this.content[this.content.length - 1];
});
messageClusterSchema.pre("validate", function () {
console.log("pre validate ran");
this.clusterTimestamp = this.content[this.content.length - 1].timestamp;
});
// assign directly to object
messageSchema.methods.objectMethod = function () {
console.log("object method called");
};
// assign with helper
messageSchema.method("helperMethod", function () {
console.log("helper method called");
});
console.log(messageSchema.methods); // {objectMethod: [Function (anonymous)], helperMethod: [Function (anonymous)]}
console.log(messageSchema.methodOptions); // { helperMethod: undefined }
const Message = mongoose.model("Message", messageClusterSchema);
export default Message;
El problema es que
objectMethod y helperMethod están en messageSchema y en el archivo Message.js, está creando un modelo de messageClusterSchema que está importando y usando en la función de socket. Ambos métodos solo se pueden llamar con una instancia modelo de messageSchema . Y es por eso que optionsMethod está llamando, pero los otros dos no. Básicamente, debe crear un modelo de messageSchema y exportarlo para usarlo en otros archivos.
En resumen, el error es:
const Message = mongoose.model("Message", messageClusterSchema);
El modelo se genera utilizando messageClusterSchema , pero los métodos se asignan a messageSchema :
messageSchema.methods.objectMethod = function () {
console.log("object method called");
};
// assign with helper
messageSchema.method("helperMethod", function () {
console.log("helper method called");
});
Deben asignarse a messageClusterSchema .