Search code examples
node.jsmongodbmongoosedust.js

How to get into another collections with foreign keys


I have these collections (books,book_genres,genres,books) my book Schema is like that

var bookModel = function () {
    var bookSchema = mongoose.Schema({
        _id: mongoose.Schema.Types.ObjectId,
        author_id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "Author",
        },
        title: String,
        description: String,
        cover: String,
        likes: Number,
    });
    return mongoose.model("Book", bookSchema);
};

module.exports = new bookModel();

I'm using dust templating and I'm rendering that collection data on my layout like that

    {#books}
             <div class="large-4 small-12 columns book">
                <div class="row img-row">
                <img src="{.cover}" alt="">
                </div>
                <div class="row">
                <h3 class="small-12">{.title}</h3>
                  <h4 class="small-5 columns ">{.author_id}</h4>
                   <h4 class="small-7 columns ">{.name}</h4>
                </div>
               
                   <div class="row p-row">
                    <p class="small-12">{.description}</p>
                   </div>
             </div>

     {/books}

my author Schema is like that

var authorModel = function () {
    var authorSchema = mongoose.Schema({
        _id: mongoose.Schema.Types.ObjectId,
        name: String,
    });
    return mongoose.model("Author", authorSchema);
};

I want to be able to reach to author name so I can render it on my layout through the author_id that I'm getting from the book Schema (for sure the id in the authors collection is the same as the author_id in the books collection)

I tried to search for some solutions but no one was using dust templating so I wasn't able to figure that out


Solution

  • You can use populate to resolve the Author reference:

    bookModel.find({}).populate('author_id').exec();
    

    You should then be able to access the referenced user fields with:

    <h4 class="small-7 columns ">{.author_id.name}</h4>
    

    In your case, you should change your code to:

    module.exports = function (router) {
      router.get('/', function (req, res) {
        Book.find({})
          .populate('author_id')
          .exec(function (err, books) {
            if (err) {
              console.log(err);
            }
            var model = { books: books };
            res.render('index', model);
          });
      });
    };