Two Model CRUD App - No relationship - Second Model
Lesson Objectives
- Create Articles Index
- Create Articles New Page
- Set up Article Model
- Create Articles Post Route
- Show Articles on Index Page
- Create Articles Show Page
- Create Articles Delete Route
- Create Articles Edit Page
- Create Articles Put Route
Create Articles Index
mkdir views/articlestouch views/articles/index.ejs
views/articles.ejs:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Articles</h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/articles/new">Create a new Article</a>
</li>
</ul>
</nav>
</header>
</body>
</html>
mkdir controllerstouch controllers/articles.js
controllers/articles.js:
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
res.render("articles/index.ejs");
});
module.exports = router;
Use the controller in server.js:
const articlesController = require("./controllers/articles.js");
app.use("/articles", articlesController);
Create Articles New Page
touch views/articles/new.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Create an Article</h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/articles">Articles Index</a>
</li>
</ul>
</nav>
</header>
<main>
<form action="/articles" method="post">
<input type="text" name="title" /><br />
<textarea name="body"></textarea><br />
<input type="submit" value="Publish Article" />
</form>
</main>
</body>
</html>
create route in controllers/articles.js
router.get("/new", (req, res) => {
res.render("articles/new.ejs");
});
Set up Article Model
touch models/articles.js
const mongoose = require("mongoose");
const articleSchema = mongoose.Schema({
title: String,
body: String,
});
const Article = mongoose.model("Article", articleSchema);
module.exports = Article;
Create Articles Create Route
controllers/articles.js
const Article = require("../models/articles.js");
//...
//...farther down the page
router.post("/", async (req, res) => {
try {
const newArticle = await Article.create(req.body);
res.redirect("/articles");
} catch (error) {
console.log(error);
};
});
Show Articles on Index Page
controllers/articles.js:
router.get("/", async (req, res) => {
try {
const foundArticles = await Article.find({});
res.render("articles/index.ejs", {
articles: foundArticles,
});
} catch (error) {
console.log(error);
};
});
views/articles/index.ejs:
<main>
<h2>List of Articles</h2>
<ul>
<% for(let i = 0; i < articles.length; i++){ %>
<li>
<a href="/articles/<%=articles[i]._id%>"><%=articles[i].title%></a>
</li>
<% } %>
</ul>
</main>
Create Articles Show Page
touch views/articles/show.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1><%=article.title%></h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/articles">Articles Index</a>
</li>
</ul>
</nav>
</header>
<main>
<section><%=article.body%></section>
</main>
</body>
</html>
towards the bottom controllers/articles.js:
//avoid this handling /new by placing it towards the bottom of the file
router.get("/:id", async (req, res) => {
try {
const foundArticles = await Article.findById(req.params.id);
res.render("articles/show.ejs", {
article: foundArticle,
});
} catch (error) {
console.log(error);
};
});
Create Articles Delete Route
controllers/articles.js:
router.delete("/:id", async (req, res) => {
try {
const removedArticle = await Article.findByIdAndRemove(req.params.id);
res.redirect("/articles");
} catch (error) {
console.log(error);
};
});
views/articles/show.ejs
<section>
<form action="/articles/<%=article._id%>?_method=DELETE" method="post">
<input type="submit" value="Delete Article" />
</form>
</section>
Create Articles Edit Page
Create a link on views/articles/show.ejs:
<section>
<a href="/articles/<%=article._id%>/edit">Edit</a>
</section>
controllers/articles.js
router.get("/:id/edit", async (req, res) => {
try {
const foundArticle = await Article.findById(req.params.id);
res.render("articles/edit.ejs", {
article: foundArticle,
});
} catch (error) {
console.log(error);
};
});
touch views/articles/edit.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Edit <%=article.title%>'s Info</h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/articles">Articles Index</a>
</li>
</ul>
</nav>
</header>
<main>
<h2>Article Attributes:</h2>
<form action="/articles/<%=article._id%>?_method=PUT" method="post">
<input type="text" name="title" value="<%=article.title%>" /><br />
<textarea name="body"><%=article.body%></textarea><br />
<input type="submit" value="Update Article" />
</form>
</main>
</body>
</html>
Create Articles Put Route
controllers/articles.js:
router.put("/:id", async (req, res) => {
try {
const updatedArticle = await Article.findByIdAndUpdate(req.params.id, req.body);
res.redirect("/articles");
} catch (error) {
console.log(error);
};
});