So, I have a Category
model with three discriminators on it. One of them, "Allowance" has a new Schema for an extra field. However, when a new Category is saved to the DB, that field will not save, it is being thrown out by Mongoose.
const CategorySchema = new mongoose.Schema({
name: {
type: String,
required: [true, "MUST HAVE A NAME"],
validate: {
validator: isSanitary,
message: "NAME CONTAINS ILLEGAL CHARACTERS"
}
},
amount: {
type: Number,
required: [true, "MUST CONTAIN AN AMOUNT"]
},
removed: {
type: Boolean,
default: false
}
}, {discriminatorKey: "kind"});
const Category = mongoose.model("Category", CategorySchema);
Category.discriminator("Income", new mongoose.Schema());
Category.discriminator("Bill", new mongoose.Schema());
Category.discriminator("Allowance",
new mongoose.Schema({
isPercent: {
type: Boolean,
required: true
}
})
);
module.exports = {
Category: Category,
CategorySchema: CategorySchema
};
Requiring the model:
const Category = require("../models/category.js").Category;
Code for creating a new Category
/*
POST: create a new Category
req.body = {
account: String (Account id)
name: String
amount: Number
kind: String (Income, Bill, Allowance)
isPercent: Boolean
}
response: Category
*/
createCategory: function(req, res){
let category = new Category({
name: req.body.name,
amount: req.body.amount,
kind: req.body.kind,
isPercent: (req.body.kind === "Allowance") ? req.body.isPercent : undefined
});
console.log(typeof(category.isPercent));
console.log(category);
res.locals.user.accounts.id(req.body.account).categories.push(category);
res.locals.user.save()
.then((user)=>{
return res.json(category);
})
.catch((err)=>{
console.error(err);
return res.json("ERROR: unable to create new category");
});
},
When a new "Allowance" is saved, it saves fine, except that isPercent
is not saved to the DB. This was working previously but then stopped when I made a tiny change. The only change is that I started exporting the Schema as well as the model. I have no idea how to even debug this issue.
Thanks for any help.
CodePudding user response:
The issue is that you are treating Category
model the same as the Allowance
category discriminator model. You cannot save isPercent
to Category
, only Allowance
. Notice in the docs that when they want to create a discriminator model, they don't use the base, they use the discriminator. Try instead exporting the discriminator models as well:
const Income = Category.discriminator("Income", new mongoose.Schema());
const Bill = Category.discriminator("Bill", new mongoose.Schema());
const Allowance = Category.discriminator("Allowance",
new mongoose.Schema({
isPercent: {
type: Boolean,
required: true
}
})
);
module.exports = {
CategorySchema,
Category,
Income,
Bill,
Allowance,
};
Then you can update the logic in your route handler to create an Allowance
or Category
conditionally:
const { Allowance, Category } = require("../models/category");
// ...
// Get correct model based on req.body data
const Model = req.body.kind === "Allowance" ? Allowance : Category;
let category = new Model({
name: req.body.name,
amount: req.body.amount,
kind: req.body.kind,
isPercent: req.body.kind === "Allowance" ? req.body.isPercent : undefined,
});
Hopefully that helps!