Дискриминатор мангустов игнорирует дополнительное поле

#javascript #mongodb #mongoose #discriminator

Вопрос:

Итак, у меня есть Category модель с тремя дискриминаторами. В одном из них, «Пособие», есть новая схема для дополнительного поля. Однако, когда новая категория сохраняется в БД, это поле не сохраняется, оно выбрасывается Мангустом.

 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 = {
    Income: Income,
    Bill: Bill,
    Allowance: Allowance,
    CategorySchema: CategorySchema
};
 

Требуется модель:

 const {Income, Bill, Allowance} = require("../models/category.js");
 

Код для создания новой категории:

 /*
    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 = {
            name: req.body.name,
            amount: req.body.amount,
            removed: false
        };

        switch(req.body.kind){
            case "Income":
                category = new Income(category);
                break;
            case "Bill":
                category = new Bill(category);
                break;
            case "Allowance":
                category = new Allowance(category);
                category.isPercent = req.body.isPercent;
                break;
        }

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

Когда сохраняется новое «Разрешение», оно сохраняется нормально, за исключением того, что isPercent оно не сохраняется в БД. Это работало раньше, но затем прекратилось, когда я внес небольшое изменение. Единственное изменение заключается в том, что я начал экспортировать схему, а также модель. Я понятия не имею, как даже отладить эту проблему.

Спасибо за любую помощь.

Комментарии:

1. Вы пробовали передавать ключ-дескриминатор для каждой схемы?

2. Просто попробовал. Никакой разницы.

3. Можете ли вы показать, как вам нужна модель и как вы создаете пособие? Как именно вы получаете доступ к пособию по модели дискриминатора?

4. @AlexanderStaroselsky Я отредактировал свой вопрос, в нем есть требование и функция для создания категории.

Ответ №1:

Проблема в том, что вы рассматриваете Category модель так же, как Allowance модель дискриминатора категорий. Вы не можете экономить isPercent Category только Allowance на том, чтобы . Обратите внимание в документах, что, когда они хотят создать модель дискриминатора, они используют не базу, а дискриминатор. Попробуйте вместо этого также экспортировать модели дискриминаторов:

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

Затем вы можете обновить логику в обработчике маршрута, чтобы создать Allowance или Category условно:

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

Надеюсь, это поможет!