In my application, I have two models - Book and Genre. I referenced the Genre model from the Book model using Schema.Types.ObjectId
. So this is how my models look like:
Book model
const mongoose = require('mongoose')
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
const bookSchema = Schema({
name: {
type: String,
trim: true,
required: 'Please enter a book name'
},
description: {
type: String,
trim: true
},
author: {
type: String,
trim: true,
},
category: {
type: String,
trim: true
},
genre: [{
type: Schema.Types.ObjectId,
ref: 'Genre'
}]
})
module.exports = mongoose.model('Book', bookSchema)
Genre model
const mongoose = require('mongoose')
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
const genreSchema = Schema({
name: {
type: String,
trim: true,
required: 'Please enter a Genre name'
}
})
module.exports = mongoose.model('Genre', genreSchema)
On the book edit page, I want to be able to show the genres available and check the ones already saved in that particular book.
Here is what I have for my routes:
router.get('/edit/:id', (req, res, next) => {
const book = Book.findOne({ _id: req.params.id })
.populate({
path: 'genre',
model: 'Genre',
populate: {
path: 'genre',
model: 'Book'
}
})
.exec()
.then((book) => {
const genres = Genre.find({ 'genre': req.params.id })
res.render('editBook', { book, genres })
})
.catch((err) => {
throw err
})
})
router.post('/edit/:id', (req, res, next) => {
req.checkBody('name', 'Name is required').notEmpty()
req.checkBody('description', 'Description is required').notEmpty()
req.checkBody('category', 'Category is required').notEmpty
const errors = req.validationErrors()
if (errors) {
console.log(errors)
res.render('editBook', { book, errors })
}
const book = Book.findOneAndUpdate({ _id: req.params.id }, req.body,
{
new: true,
runValidators:true
}).exec()
.then((book) => {
res.redirect(`/books/edit/${book._id}`)
})
.catch((err) => {
res.send({
'message': err
})
})
})
And the part where the genre should be displayed looks like this:
.form-group
label.col-lg-2.control-label Genre
.col-lg-10
for genre in genres
.checkbox
input.checkbox(type='checkbox', name='genre', id=genre._id, value=genre._id, checked=genre.checked)
label(for=genre._id) #{genre.name}
What am I possibly doing wrong? I have tried all the solutions I know but nothing has worked.
P.S: mongoose-deep-populate plugin has not been updated for a long time. The solution I used worked fine for the show routes and can be found here - https://stackoverflow.com/a/43464418/2119604