Невозможно заполнить мои поля с помощью populate()

Это моя модель product.js

const mongoose = require("mongoose");
const { Schema } = mongoose;

const productsSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, "Name is required"]
    },
    imgURL: {
        type: String,
        required: [true, "imgURL is required"]
    },
    description: {
        type: String,
        required: [true, "Description is required"]
    },
    categoryName: {
        type: String,
        required: [true, "Category is required"]
    },
    price:{
        type: Number,
        required: [true, "Price is required"],
        default: false
    },
    isActive:{
        type: Boolean,
        default: true
    },
    variations: {
        size:[
            {
            type: Schema.Types.ObjectId,
            ref: 'Size'
            }
        ]
    }
})

const Products = mongoose.model('Products', productsSchema);

module.exports = Products;

и вот мой код:

const Products = require("../models/products");
const Size = require("../models/size")

module.exports.createProduct = (req,res) => {
    if (!req.user.isAdmin) {
        return Promise.reject("Only administrators can create products")
    }

    const newProduct = new Products ({
        name: req.body.name,
        imgURL: req.body.imgURL,
        description: req.body.description,
        categoryName: req.body.categoryName,
        isActive: req.body.isActive,
        price: req.body.price
    });

    return newProduct.save()
    .then(() => {
        return res.send(true);
    })
    .catch((error) => {
        console.error(error);
        if (error.name === 'ValidationError') {
            return res.status(400).json({message: 'Validation Error', errors: error.errors});
        }
        return res.status(500).json({message: 'Internet server error'});
    });
};


module.exports.getAllActiveProducts = (req, res) => {
    Products.find({ isActive: true })
            .populate({ path: 'variations.size', model: 'Size'})

        .then(result => {
            console.info("Found products with variations:", result);
            return res.send(result);
        })
        .catch(err => {
            console.error("Error fetching active products:", err);
            return res.status(500).json({ error: "Failed to fetch active products" });
    });
};

Это моя модель размера

const mongoose = require("mongoose");

const sizeSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, "Size is required"]
    },
    isActive: {
        type: Boolean,
        default: true
    }
})

const Size = mongoose.model('Size', sizeSchema);

module.exports = Size;

Я хочу заполнить поле размера, но, похоже, у меня возникла проблема с подключением моей модели (Размер), поскольку она возвращает пустой массив.

Посмотреть скриншот моего Почтальона

Я уже использовал ref и populate для заполнения поля размера, но это не работает.

Коллекция размеров: Скриншот

🤔 А знаете ли вы, что...
Node.js поддерживает платформу Event Loop, что обеспечивает высокую производительность при обработке запросов.


1
65
1

Ответ:

Решено

Добавьте это в свою модель Product, удалив существующую variations.

variations: [
            {
            type: Schema.Types.ObjectId,
            ref: 'Size'
            }
        ]

Затем создайте Product вот так. Попробуйте использовать async((req,res) =>{.., поскольку мой код соответствует этому подходу.

const Products = require('./path_to_product_model');
const Size = require('./path_to_size_model');

//create "Size" Documents
 
const smallSize = new Size({ name: 'Small' });
const mediumSize = new Size({ name: 'Medium' });

await smallSize.save();
await mediumSize.save();

//create "Product" Document
 const newProduct = new Products ({
    name: req.body.name,
    imgURL: req.body.imgURL,
    description: req.body.description,
    categoryName: req.body.categoryName,
    isActive: req.body.isActive,
    price: req.body.price ,
    variations: [smallSize._id, mediumSize._id]
});

await newProduct.save();

Чтобы получить Product и заполнить его поле variations соответствующим Size documents, сделайте следующее:

const product = await Products.find({ isActive: true}).populate('variations');

Попробуйте это. Это сработает.

Для получения дополнительной информации о populate() вы можете перейти по ссылке на документ, приведенной ниже.

https://mongoosejs.com/docs/populate.html#saving-refs

N:B: - В приведенном выше блоке кода я использовал async-await для получения данных на основе Promise. Если вы хотите, вы можете измениться соответствующим образом.