본문 바로가기

Youtube Clone Coding

프로필에 영상 리스트 보여주기

이제 특정 유저의 프로필에 들어갔을때, 해당 유저가 올린 영상을 보여주는 작업을 할 것이다. 일단 현재의 코드는 다음과 같다.

export const see = async (req, res) => {
    const { id } = req.params;
    const user = await User.findById(id);
    if (!user) {
        return res.status(404).render("404", { pageTitle: "유저가 존재하지 않음." });
    }
    return res.render("users/profile", { pageTitle: user.name, user });
}

지금은 id를 통해 유저를 찾고 있는데, 추가로 id를 owner로 가진 영상을 찾을 수 있다.

export const see = async (req, res) => {
    const { id } = req.params;
    const user = await User.findById(id);
    if (!user) {
        return res.status(404).render("404", { pageTitle: "유저가 존재하지 않음." });
    }
    const videos = await Video.find({ owner: user._id });
    return res.render("users/profile", { pageTitle: user.name, user, videos });
}

find 메서드를 통해 owner의 값이 user의 id와 같은 영상들만 찾는 코드이다. 그리고 그 변수를 profile페이지를 렌더링 할 때, videos를 넘겨준다. 이제 profile.pug에서 보여주는 코드를 작성한다. 

extends ../base
include ../mixins/video

block content 
    each video in videos 
        +video(video)

홈페이지에서 사용했던 코드를 그대로 사용한다. 이렇게되면 유저의 프로필에서 유저가 올린 영상들을 볼 수 있게된다. 

 

+++++++++

이 코드에서도 populate를 사용하여 같은 코드를 작성 할 수 있다.

일단 User 모델의 스키마를 수정해야 한다. 말했듯이, Video는 하나의 owner를 가질 수 있고, User는 여러개의 video를 가질 수 있다. 따라서 다음과 같이 추가해준다.

const userSchema = new mongoose.Schema({
    email: { type: String, required: true, unique: true },
    avatarUrl: String,
    socialOnly: { type: Boolean, default: false },
    githubId: { type: Number },
    username: { type: String, required: true, unique: true },
    password: { type: String },
    name: { type: String, required: true },
    location: String,
    videos: [{ type: mongoose.Schema.Types.ObjectId, ref: "Video" }],
});

videos "배열" 을 추가해주었고, ref는 Video 모델로 해주었다. 새로 업로드하는 영상의 id를 여기에 추가해 주는 것이다. 이제 videoController를 수정 해주어야 한다. postUpload에 가서 수정해준다. 

export const postUpload = async (req, res) => {
  const {
    user: { _id },
  } = req.session;
  const { path: fileUrl } = req.file;
  const title = req.body.uploadTitle;
  const description = req.body.description;
  const hashtags = req.body.hashtags;

  try {
    const newVideo = await Video.create({
      title: title,
      description: 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: "영상 업로드", errorMessage: error._message, });
  }
}

이전에는 그냥 Video.create만 했었는데, 지금은 일단 생성하고 이를 newVideo에 저장한다. 그리고 id를 통해 user를 찾은후, 유저의 videos 배열에 newVideo의 id를 push 해준다. 이렇게 되면 해당 유저의 db에는 videos배열이 생기고 그 안에 id가 들어가게 된다. 

 

userController의 see 컨트롤러도 수정이 필요하다. videos 객체를 user 모델에 추가했으므로 user에서 뽑아서 쓸 수 있다.

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: "유저가 존재하지 않음." });
    }
    return res.render("users/profile", { pageTitle: user.name, user });
}

위처럼 populate를 사용하고 profile템플릿에 user를 넘겨주면 profile.pug에서 user.videos 와 같이 사용가능하다!

'Youtube Clone Coding' 카테고리의 다른 글

webpack으로 scss 쓰기  (0) 2022.11.23
webpack  (0) 2022.11.23
ref와 populate  (0) 2022.11.22
Video와 User 모델 연결 & 영상 보여주기  (0) 2022.11.22
유저 프로필 페이지  (2) 2022.11.22