Open In App

How to Create Relationships with Mongoose and Node.JS?

Last Updated : 31 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Mongoose is a powerful ODM (Object Data Modeling) library for MongoDB and Node.js, allowing developers to define schemas and interact with MongoDB using models. Creating relationships between schemas is important for building complex applications with interrelated data. This article will guide you through setting up and managing relationships with Mongoose in a Node.js application.

Prerequisites

Steps on How to Create Relationships with Mongoose and Node.JS

Step 1: Create a New Directory

At first create a new directory for your project and navigate into it.

mkdir Your_folder_name
cd Your_folder_name

Step 2: Initialize a New Node.js Project

After that, you have to Initialize a new node project using npm.

npm init -y

Step 3: Install required packages

Then install the the required package using npm.

npm install express mongoose ejs body-parser

Project Structure

Screenshot-_536_
Folder structure

Dependencies

"dependencies": {
"body-parser": "^1.20.2",
"ejs": "^3.1.10",
"express": "^4.19.2",
"mongoose": "^8.5.1"
}
}

Example: Below is the code example of how to Create Relationships with Mongoose and Node.JS

HTML
<!-- views/layout.ejs code... -->

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mongoose Relations</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap">
    <link rel="stylesheet" href="/style.css">
</head>

<body>
    <header>
        <h1>Mongoose Relations</h1>
        <nav>
            <ul>
                <li class="nav-lists"><a href="/authors">Authors</a></li>
                <li class="nav-lists"><a href="/books">Books</a></li>
            </ul>
        </nav>
    </header>
</body>

</html>
HTML
<!-- views/books.ejs code... -->

<%- include('layout') %>

    <h2 class="books-heading">Books</h2>
    <form action="/books" method="POST">
        <label for="title">Title</label>
        <input type="text" name="title" id="title" required>

        <label for="author">Author</label>
        <select name="author" id="author" required>
            <% authors.forEach(author=> { %>
                <option value="<%= author._id %>">
                    <%= author.name %>
                </option>
                <% }) %>
        </select>

        <button type="submit">Add Book</button>
    </form>

    <ul class="books-lists">
        <% books.forEach(book=> { %>
            <li>
                <%= book.title %> by <%= book.author.name %>
            </li>
            <% }) %>
    </ul>
HTML
<!-- views/authors.ejs code... -->

<%- include('layout') %>

    <h2 class="author-heading">Authors</h2>
    <form action="/authors" method="POST">
        <label for="name">Name</label>
        <input type="text" name="name" id="name" required>
        <button type="submit">Add Author</button>
    </form>

    <ul class="author-lists">
        <% authors.forEach(author=> { %>
            <li>
                <%= author.name %>
            </li>
            <% }) %>
    </ul>
CSS
/* public/style.css code.... */
body,
h1,
h2,
p,
ul {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Roboto', sans-serif;
    background-color: #f4f7f6;
    color: #333;
    line-height: 1.6;
}

header {
    background-color: rgb(29, 231, 29);
    color: white;
    padding: 15px 0;
    text-align: center;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

header h1 {
    margin: 0;
    font-size: 24px;
    font-weight: 400;
}

header nav ul {
    list-style: none;
    display: flex;
    justify-content: center;
    padding: 0;
    margin: 10px 0 0;
}

.nav-lists {
    background: #007bff;
}

header nav ul li {
    margin: 0 15px;
}

header nav ul li a {
    color: white;
    text-decoration: none;
    font-size: 16px;
}

header nav ul li a:hover {
    text-decoration: underline;
}

.books-heading {
    font-size: 22px;
    margin-bottom: 20px;
    color: #007bff;
    padding-bottom: 10px;
    margin-left: 35rem;
    font-size: 36px;
}

.author-heading {
    font-size: 22px;
    margin-bottom: 20px;
    color: #007bff;
    padding-bottom: 10px;
    margin-left: 35rem;
    font-size: 36px;
}

form {
    margin-bottom: 30px;
    padding: 20px;
    background-color: #e9ecef;
    border-radius: 8px;
    width: 30vw;
    margin-left: 25rem;
}

form label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
    color: #495057;
}

form input,
form select,
form button {
    display: block;
    width: 100%;
    padding: 10px;
    margin-bottom: 15px;
    border: 1px solid #ced4da;
    border-radius: 4px;
}

form input:focus,
form select:focus {
    border-color: #80bdff;
    outline: none;
}

form button {
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

form button:hover {
    background-color: #0056b3;
}


ul {
    list-style: none;
    padding: 0;
}

ul li {
    background-color: #f8f9fa;
    border: 1px solid #e9ecef;
    margin-bottom: 10px;
    padding: 15px;
    border-radius: 4px;
    font-size: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.author-lists {
    margin-left: 25rem;
    width: 35vw;
}

.author-lists li:nth-child(even) {
    background-color: #e9ecef;
}

.books-lists {
    margin-left: 25rem;
    width: 35vw;
}

.books-lists li:nth-child(even) {
    background-color: #e9ecef;
}
JavaScript
// app.js code....

const express = require("express");
const bodyParser = require("body-parser");
const connectDB = require("./database/db");
const app = express();
const PORT = process.env.PORT || 3000;

// Connect to the database
connectDB();

app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));

const authorRouter = require("./routes/authors");
const bookRouter = require("./routes/books");

app.use("/authors", authorRouter);
app.use("/books", bookRouter);

app.get("/", (req, res) => {
    res.redirect("/authors");
});

app.listen(PORT, (err) => {
    if (err) {
        console.log(err);
    } else {
        console.log(`Server is running on http://localhost:${PORT}`);
    }
});
JavaScript
// routes/authors.js code .....

const express = require("express");
const router = express.Router();
const Author = require("../models/author");

router.get("/", async (req, res) => {
    const authors = await Author.find({});
    res.render("authors", { authors });
});

router.post("/", async (req, res) => {
    const author = new Author({
        name: req.body.name,
    });
    await author.save();
    res.redirect("/authors");
});

module.exports = router;
JavaScript
// routes/books.js code .....

const express = require("express");
const router = express.Router();
const Book = require("../models/book");
const Author = require("../models/author");

router.get("/", async (req, res) => {
    const books = await Book.find({}).populate("author");
    const authors = await Author.find({});
    res.render("books", { books, authors });
});

router.post("/", async (req, res) => {
    const book = new Book({
        title: req.body.title,
        author: req.body.author,
    });
    await book.save();
    res.redirect("/books");
});

module.exports = router;
JavaScript
// models/author.js code .....

const mongoose = require('mongoose');

const authorSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    }
});

module.exports = mongoose.model('Author', authorSchema);
JavaScript
// models/book.js code .....


const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const bookSchema = new Schema({
    title: {
        type: String,
        required: true
    },
    author: {
        type: Schema.Types.ObjectId,
        ref: 'Author',
        required: true
    }
});

module.exports = mongoose.model('Book', bookSchema);
JavaScript
// database/db.js

const mongoose = require('mongoose');

const connectDB = async () => {
    try {
        await mongoose.connect('mongodb://localhost:27017/mongoose-relations', {
           
        });
        console.log('Database is connected');
    } catch (err) {
        console.error('Error connecting to the database:', err);
        process.exit(1);
    }
};

module.exports = connectDB;

To run the code write in the command prompt.

node app.js

And open a new tab of your browser and type the following command to show the output.

http://localhost:3000/

Output :


Database Output:



Next Article

Similar Reads