Let's assume we have two models
1.Mobile
2.Laptop
We want to add review feature for customers in our application. For one review model there will be multiple references.
This process is bit complicated, but we will go through this.
- Create Review model
const mongoose = require('mongoose');
const reviewSchema = new mongoose.Schema(
{
review: {
type: String,
required: [true, 'Review is required'], //Review: Good product
min: 3,
max: 200,
},
rating: {
type: Number,
required: [true, 'Review is required'], //Rating: 5
min: 1,
max: 5,
default: 4,
},
product: {
type: mongoose.Schema.Types.ObjectId,
refPath: 'onModel', // product => mobile,laptop
required: [true, 'Review must belong to a product'],
},
onModel: {
type: String,
required: true,
enum: ['Laptop', 'Mobile'],
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: [true, 'Review must belong to a user'], //user who reviewed your product
},
createdAt: {
type: Date,
default: Date.now(),
},
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true }, //for virtual property.
}
);
reviewSchema.pre(/^find/, function (next) {
this.populate({ path: 'product', select: 'name image slug' }); //this will populate the product details in the review route for all the find operations. example: api/review
this.populate({
path: 'user',
select: 'name image',
}); //this will populate the user details in the review route
next();
});
const Review = mongoose.model('Review', reviewSchema);
module.exports = Review;
- Create Review middleware for post request
exports.createReview=async (req,res,next)=>{
try{
const { review,rating,user,onModel,product} = req.body;
await Review.create({review,rating,user,onModel,product})
// logic
}catch(err){
//error logic
}
}
- Virtual Populate in Mobile model
const mobileSchema = new mongoose.Schema(
{
//logic
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
//virtual populating
mobileSchema.virtual('reviews', {
ref: 'Review', //referencing review model
localField: '_id', //mobile object id
foreignField: 'product', //Review model field for mobile object id
});
const Mobile = mongoose.model('Mobile', mobileSchema);
module.exports = Mobile;
- Populating reviews of Mobile model
exports.getMobileById=async (req,res,next)=>{
try{
const mobile=await Mobile.findById(req.params.id).populate({ path: 'reviews', select: 'review rating user createdAt'});
//other logics
}catch(err){
//error logic
}
}
Thank you for reading
Connect With Me : Github LinkedIn
#mongoose #dynamic #reference
Top comments (0)