Mongoose 설치와 사용방법
이 수업에서는 데이터베이스로 MongoDB를 사용했다. 그리고 MongoDB를 Node.js에서 사용할 수 있게 도와주는 것이 Mongoose이다.
설치(먼저, MongoDB를 설치해야 함.)
npm i mongoose
사용
//db.js
import mongoose from "mongoose";
import dotenv from "dotenv";
dotenv.config();
mongoose.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useFindAndModify: false,
});
const db = mongoose.connection;
const handleOpen = () => console.log("✅ Connected to DB");
const handleError = () => console.error.bind(console, "connection error:");
db.once("open", handleOpen);
db.on("error", handleError);
dotenv는 우리의 중요한 정보들을 숨길 수 있게 도와주는 것이다.
npm i dotenv로 설치한 후, .env파일을 만들어서 그 안에 데이터베이스가 연결되어있는 URL(MONGO_URL)을 넣어주었다.
모델 만들기
models라는 폴더를 만들고 거기에 Video.js파일을 만들었다.
//Video.js
import mongoose from "mongoose";
const VideoSchema = new mongoose.Schema({
fileUrl: {
type: String,
required: "File URL is required",
},
title: {
type: String,
required: "Title is required",
},
description: String,
views: {
type: Number,
default: 0,
},
createAt: {
type: Date,
default: Date.now,
},
comments: [ //Comment.js와 연결
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}
]
});
const Video = mongoose.model("Video", VideoSchema);
export default Video;
마지막에서 두 번째 줄이 처음에는 잘 이해가 안 되었는데, Mongoose홈페이지의 글을 보고 이해됐다. model함수는 스키마의 복사본을 만들어준다고 한다. 그러니까 마지막에서 두 번째 줄의 의미는 VideoSchema를 사용해 "Video"라는 이름의 모델을 만들고 나서 VideoSchema의 복사본을 Video에 넣는 것이다.
각 비디오에 댓글도 있으니까 Comment.js도 추가한다. (둘을 연결하는 코드는 둘 중 하나에 쓰면 된다. 여기서는 Video.js에 씀)
import mongoose from "mongoose";
const CommentSchema = new mongoose.Schema({
text: {
type: String,
required: "Text is required"
},
createdAt: {
type: Date,
default: Date.now
}
});
const Comment = mongoose.model("Comment", CommentSchema);
export default Comment;
업로드하기(Create)
먼저, multer모듈을 설치해준다. multer는 파일 전송을 도와주는 모듈이다.
사용방법
먼저, upload 하는 form에 가서 enctype="multipart/form-data"를 꼭 추가해줘야한다.
그리고 아래처럼 미들웨어에 코드를 추가하고 router도 수정한다.
//middleware.js
import multer from "multer";
const multerVideo = multer({ dest: "uploads/videos/" });
export const uploadVideo = multerVideo.single("videoFile");
//videoRouter.js
//videoRouter.post(routes.upload, postUpload);
videoRouter.post(routes.upload, uploadVideo, postUpload);
마지막으로 postUpload컨트롤러를 추가해준다.
import Video from "../models/Video";
export const postUpload = async (req, res) => {
const {
body: { title, description },
file: { path }
} = req;
const newVideo = await Video.create({
fileUrl: path,
title,
description
});
res.redirect(routes.videoDetail(newVideo.id));
};
multer덕분에 req.file에서 사용자가 upload 할 때 보내온 정보들과 multer가 추가적으로 만든 정보들을 얻을 수 있다. 그래서 우리는 Video모델에 id를 정의하지 않았지만, multer가 id를 만들어주었기 때문에 newVideo.id를 사용할 수 있다. 그리고 자바스크립트는 기본적으로 비동기 방식으로 동작하기 때문에 Video.create가 끝나기 전에 밑의 코드가 실행될 수 있다. 그래서 await을 사용해 동기로 바꿔준다.
MongoDB에 데이터를 추가하는 것은 완료되었으니 이제 데이터를 가져와서 보여주면 된다.
home컨트롤러를 수정해주는 데, 아래와 같이 모든 데이터를 가져와서 home.pug에 넘겨주면 된다.
import Video from "../models/Video";
export const home = async (req, res) => {
try {
const videos = await Video.find({});
res.render("home", { pageTitle: "Home", videos });
} catch (error) {
console.log(error);
res.render("home", { pageTitle: "Home", videos: [] });
}
};
수정하기(Update)
findOneAndUpdate함수를 사용하면 몽구스가 업데이트를 해준다.
export const getVideoEdit = async (req, res) => {
const {
params: { id },
} = req;
try {
const video = await Video.findById(id);
res.render("videoEdit", { title: `Edit ${video.title}`, video });
} catch (error) {
res.redirect(routes.home);
}
};
export const postVideoEdit = async (req, res) => {
const {
params: { id },
body: { title, description },
} = req;
try {
await Video.findOneAndUpdate(id, { title, description });
res.redirect(routes.videoDetail(id));
} catch (error) {
res.redirect(routes.home);
}
};
삭제하기(Delete)
findOneAndDelete함수를 사용하면 몽구스가 삭제해준다. (단, 데이터베이스에 있는 데이터만 지워지고 uploads밑에 있는 파일들은 지워지지 않는다.)
export const videoDelete = async (req, res) => {
const {
body: { id },
} = req;
try {
await Video.findOneAndDelete(id);
} catch (error) {}
res.redirect(routes.home);
};
'클론코딩 > 유튜브' 카테고리의 다른 글
챌린지를 하면서 알게된 내용들 (2) | 2020.07.06 |
---|---|
#5 - Passport를 사용해 User Authentication하기 (2) | 2020.07.04 |
#4 - Webpack을 이용해 Styling하기 (0) | 2020.05.11 |
#2 - Pug로 뼈대 만들기 (0) | 2020.05.05 |
#1 - Express.js 기반 다지기 (0) | 2020.05.01 |