2017-09-29 4 views
0

Dans mon application, j'ai deux modèles - Book et Genre. J'ai référencé le modèle de genre du modèle de livre en utilisant Schema.Types.ObjectId. Voilà donc comment mes modèles ressemblent:Le modèle référencé ne s'affiche pas dans la page d'édition lors de l'utilisation.

modèle du livre

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) 

modèle Genre

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) 

Sur la page d'édition du livre, je veux être en mesure de montrer les genres disponibles et vérifiez la ceux déjà enregistrés dans ce livre particulier.

Voici ce que j'ai pour mes itinéraires:

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

Et la partie où le genre doit être affiché ressemble à ceci:

.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} 

Qu'est-ce que je fais peut-être mal? J'ai essayé toutes les solutions que je connais, mais rien n'a fonctionné.

P.S: Le plugin mongoose-deep-populate n'a pas été mis à jour depuis longtemps. La solution que j'ai utilisée a bien fonctionné pour les routes d'exposition et peut être trouvée ici - https://stackoverflow.com/a/43464418/2119604

Répondre

0

Vous utilisez incorrectement la méthode mongose ​​populate. populate renvoie l'objet dont un parent et un ou plusieurs modèles référencés. Dans votre cas book a un éventail de genres (BTW, il a un nom erroné dans votre schéma, unique au lieu de pluriel), de sorte que vous n'avez pas besoin demande supplémentaire pour charger les genres:

router.get('/edit/:id', (req, res, next) => { 
    Book 
    .findOne({ _id: req.params.id }) 
    .populate('genre') 
    .exec() 
    .then(book => res.render('editBook', { book, genres: book.genre })) 
    .catch(err => { 
     console.log(err); 
     next(err); 
    }); 
});