const videoSchema = new mongoose.Schema({
fileUrl: { type: String, required: true },
title: { type: String, required: true, trim: true, maxlength: 80 },
description: { type: String, required: true, trim: true, minlength: 10 },
createdAt: { type: Date, required: true, default: Date.now },
hashtags: [{ type: String, trim: true }],
meta: {
views: { type: Number, default: 0, required: true },
rating: { type: Number, default: 0, required: true },
},
owner: { type: mongoose.Schema.Types.ObjectId, required: true, ref: "User" },
});
video를 upload할때 postUpload controller에서 owner을 설정해 주어야함
const {
user: { _id },
} = req.session;
await Video.create({
title,
description,
fileUrl,
owner: _id,
hashtags: Video.formatHashtags(hashtags),
});
loggedInUser은 middleware으로 설정한 값임. (req.session.user)
loggedInUser._id와 video.owner은 서로 type이 달라 String으로 바꿔 줘야함.
if String(loggedInUser._id) === String(video.owner)
a(href=`${video.id}/edit`) Edit Video →
br
a(href=`${video.id}/delete`) Delete Video →
export const watch = async (req, res) => {
const { id } = req.params;
const video = await Video.findById(id);
const owner = await User.findById(video.owner);
if (!video) {
return res.status(404).render("404", { pageTitle: "Video not found" });
}
return res.render("watch", { pageTitle: video.title, video, owner });
};
div
small Uploaded by #{owner.name}
populate를 설정하면 videodml owner에 user정보가 들어감
밑의 코드는 populate한 video의 내용
{
meta: { views: 0, rating: 0 },
_id: new ObjectId("6175061eeea27b4b08e9dd3f"),
fileUrl: 'uploads/videos/0133df49bec4e9e7487960596dae8a9c',
title: 'wqe',
description: 'qwewwqewqeqwewq',
hashtags: [ '#wetube', '#coding', '#js', '#ts' ],
owner: {
_id: new ObjectId("617505c656b9a7752860d587"),
email: 'dlwogns3413@naver.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/62169861?v=4',
socialOnly: true,
username: 'abc5259',
password: '$2b$05$PHglLSEBLvyVBEi0gqYQZ.7yuvB16BDWWifDeVejlsoDT5.GvrBg.',
name: 'LeeJaeHoon',
location: null,
__v: 0
},
createdAt: 2021-10-24T07:07:10.918Z,
__v: 0
}
밑의 코드는 populate하기 전 video의 내용
{
meta: { views: 0, rating: 0 },
_id: new ObjectId("6175061eeea27b4b08e9dd3f"),
fileUrl: 'uploads/videos/0133df49bec4e9e7487960596dae8a9c',
title: 'wqe',
description: 'qwewwqewqeqwewq',
hashtags: [ '#wetube', '#coding', '#js', '#ts' ],
owner: new ObjectId("617505c656b9a7752860d587"),
createdAt: 2021-10-24T07:07:10.918Z,
__v: 0
}
populate의 인자로는 Video Model에 설정해둔 owner이 들어가야함
export const watch = async (req, res) => {
const { id } = req.params;
const video = await Video.findById(id).populate("owner");
console.log(video);
if (!video) {
return res.status(404).render("404", { pageTitle: "Video not found" });
}
return res.render("watch", { pageTitle: video.title, video });
};
div
small Uploaded by
a(href=`/users/${video.owner._id}`) #{video.owner.name}
if String(loggedInUser._id) === String(video.owner._id)
a(href=`${video.id}/edit`) Edit Video →
br
a(href=`${video.id}/delete`) Delete Video →
const userSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
avatarUrl: { type: String },
socialOnly: { type: Boolean, default: false },
username: { type: String, required: true, unique: true },
password: { type: String },
name: { type: String, required: true },
location: { type: String },
videos: [{ type: mongoose.Schema.Types.ObjectId, ref: "Video" }],
});
create 메소드는 새로만들어진 video를 리턴한다.
export const postUpload = async (req, res) => {
const {
user: { _id },
} = req.session;
const { path: fileUrl } = req.file;
const { title, description, hashtags } = req.body;
try {
const newVideo = await Video.create({
title,
description,
fileUrl,
owner: _id,
hashtags: Video.formatHashtags(hashtags),
});
const user = await User.findById(_id);
user.videos.push(newVideo._id);
user.save();
return res.redirect("/");
} catch (error) {
return res.status(400).render("upload", {
pageTitle: `Upload Video`,
errorMessage: error._message,
});
}
};
user.save()를 할때마다 User에 설정해둔 middleware(비밀번호 hash)가 발생하므로 추가적인 코드를 작성 해주어야 한다.
isModified메소드는 인자에 바뀌는 것을 넣고 바뀌면 true를 리턴해줌.
userSchema.pre("save", async function () {
//this는 create되는 User을 가리킴
if (this.isModified("password")) {
this.password = await bcrypt.hash(this.password, 5);
}
});
export const see = async (req, res) => {
const { id } = req.params;
const user = await User.findById(id).populate("videos");
if (!user) {
return res.status(404).render("404", { pageTitle: "User not found." });
}
return res.render("users/profile", {
pageTitle: `${user.name} Profile`,
user,
});
};
{
_id: new ObjectId("6175756c40a60952e39093ae"),
email: 'dlwogns3413@naver.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/62169861?v=4',
socialOnly: true,
username: 'abc5259',
password: '$2b$05$0IetvgkbDNZZYbgHN4Di3uKIIDjYZilaPdpkNxOJXf45o146oTaDm',
name: 'LeeJaeHoon',
location: null,
videos: [ new ObjectId("6175757b40a60952e39093b1") ],
__v: 1
}
{
_id: new ObjectId("6175756c40a60952e39093ae"),
email: 'dlwogns3413@naver.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/62169861?v=4',
socialOnly: true,
username: 'abc5259',
password: '$2b$05$0IetvgkbDNZZYbgHN4Di3uKIIDjYZilaPdpkNxOJXf45o146oTaDm',
name: 'LeeJaeHoon',
location: null,
videos: [
{
meta: [Object],
_id: new ObjectId("6175757b40a60952e39093b1"),
fileUrl: 'uploads/videos/6e4d8b7b59e2799c82f3a2011a19a5a6',
title: 'wq',
description: 'good Defaultwqeqw',
hashtags: [Array],
owner: new ObjectId("6175756c40a60952e39093ae"),
createdAt: 2021-10-24T15:02:19.879Z,
__v: 0
}
],
__v: 1
}
둘이 type이 달라 String으로 변환 해 주어야 함.
if (String(video.owner) !== String(_id)) {
return res.status(403).redirect("/");
}
user.videos.splice(user.videos.indexOf(id), 1);
user.save();