-> 그 이유는 우리가 router에 추가할 수 있는 Regular Expression(정규표현식)때문에 생기는 것.
위에서는 (\d+)가 정규표현식. 이건 숫자만으로 된 id를 다루기엔 좋지만 mongoDB가 만든 id
형식과는 맞지 않음.
a(href=`/videos/${video.id}`)=video.title
videoRouter.get("/:id(\\d+)", watch);
videoRouter.route("/:id(\\d+)/edit").get(getEdit).post(postEdit);
// ex: http://localhost:4000/videos/62a6f150841eb28279d5c416
videoRouter.route("/upload").get(getUpload).post(postUpload);
videoRouter.route("/upload").get(getUpload).post(postUpload);
videoRouter.get("/:id", watch);
videoRouter.route("/:id/edit").get(getEdit).post(postEdit);
videoRouter.get("/:id([0-9a-f]{24})", watch);//24글자의 16진수라는 뜻.
videoRouter.route("/:id([0-9a-f]{24})/edit").get(getEdit).post(postEdit);
videoRouter.route("/upload").get(getUpload).post(postUpload);
extends base.pug
block content
div
p=video.description
small=video.createdAt
a(href=`${video.id}/edit`) Edit Video →
export const watch = async(req,res) => {
const id = req.params.id;
const video = await Video.findById(id);//Video에서 찾아도 되는 이유: 이 파일에 mongoose가 import돼 있으며, 이는 mongoDB와 이어져 있고 이를 이용해 Video model을 만들었으므로 자연스레 찾을 수 있게됨.
return res.render("watch",{pageTitle : video.title, video});
}
await Adventure.findOne({ country: 'Croatia' }).exec();
export const watch = async(req,res) => {
const id = req.params.id;
const video = await Video.findById(id);//Video에서 찾아도 되는 이유: 이 파일에 mongoose가 import돼 있으며, 이는 mongoDB와 이어져 있고 이를 이용해 Video model을 만들었으므로 자연스레 찾을 수 있게됨.
if(!video){
return res.render("404", { pageTitle: "Video not found." });
}
return res.render("watch",{pageTitle : video.title, video});
}
extends base.pug
doctype html
html(lang="ko")
head
title #{pageTitle} | WeTube
link(rel="stylesheet" href="https://unpkg.com/mvp.css")
body
header
h1=pageTitle
nav
ul
li
a(href="/videos/upload") Upload Video
li
a(href="/") Home
main
block content
include partials/footer.pug
extends base.pug
block content
h4 Update Video
form(method="POST")
input(name="title", placeholder="Video Title", value=video.title,required)
input(name="description",placeholder="Description", required, type="text", minlength=20, value=video.description)
input(name="hashtags",placeholder="Hashtags, separated by comma.", required, type="text", value=video.hashtags.join())
input(type="submit",value="save")
export const getEdit = async(req,res) => {
const id = req.params.id;
const video = await Video.findById(id);
if(!video){
return res.render("404", { pageTitle: "Video not found." });
}
return res.render("edit",{pageTitle:`Editing ${video.title}`, video});
}
-> id로 비디오를 찾고, 변경내용을 update해줌.
findByIdAndUpdate MDN
findOneAndUpdate MDN
-> 원하는 모델의 propery를 적어 넣으면 그것에 따라 DB에서 필터링해서 원하는 게 존재하는지 알아낼 수 있음. return 값은 boolean(true/false)임
-> getEdit처럼 화면에 나타나야할 경우엔 findById가 적합하지만, 굳이 video객체를 템플릿에 보이거나 가져올 필요가 없는 경우엔 exists가 더 적합하다.
Model.exists MDN
//별로 좋지 않은 코드로 작성
export const postEdit = async (req, res) => {//post를 하면 mongoDB 내의 값을 변경해줌.
const {id} = req.params;
const {title, description, hashtags } = req.body;
const video = await Video.findById(id);
if(!video){
return res.render("404", { pageTitle: "Video not found." });
}
video.title = title;
video.description = description;
video.hashtags = hashtags.split(",").map((word) => word.startsWith("#") ? word :`#${word}`);//startsWith(word): word로 시작한다면 이란 뜻인듯.
await video.save();//post로 바꾼 mongoDB내의 변경 내용을 저장함. <- 이게 없으면 저장이 안됨.
return res.redirect(`/videos/${id}`);
}
// 그나마 좋은 코드 !!!!!!!!!!!!!!!!!!!!
export const postEdit = async (req, res) => {//post를 하면 mongoDB 내의 값을 변경해줌.
const {id} = req.params;
const {title, description, hashtags } = req.body;
const video = await Video.exists({_id:id});//video: DB에서 검색한 영상 object , Video: 우리가 만든 비디오 모델임.
if(!video){
return res.render("404", { pageTitle: "Video not found." });
}
await Video.findByIdAndUpdate(id, {
title:title,
description:description,
hashtags:hashtags.split(",").map((word) => word.startsWith("#") ? word :`#${word}`),
})
return res.redirect(`/videos/${id}`);
}