Video Owner #01

0_cyberlover_0·2022년 5월 9일
0

Node.JS #06

목록 보기
1/1
post-thumbnail

Video를 user와 연결하는 작업을 해본다.

현재는 videouser가 서로 연결되어 있지 않다.

mongoosemongodb를 활용해 연결하려면 id를 사용해야 한다.

왜냐하면 id는 하나밖에 없고 랜덤 숫자이기 때문이다.

그러면 현재 가지고 있는 id를 가지고 연결해 보도록 하겠다.

user에는 해당 user가 업로드한 모든 영상의 id를 저장 해준다.

그리고 video에는 해당 영상을 올린 userid를 저장한다.

현재는 이해하지 못해도 코드를 보면 알게 될거다.

먼저 videoSchemaowner를 추가해준다.

video.js에서

const videoSchema = new mongoose.Schema({
  title: { type: String, required: true, trim: true, maxLength: 80 },
  fileUrl: { type: String, reqired: true },
  description: { type: String, required: true, trim: true, maxLength: 20 },
  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 },
  },
  ower: { type: mongoose.Schema.Types.ObjectId, reqired: true, ref: "User" },
});

ownertypenumber,string,date가 아니고 objectId이다.

그러나 objectId문자 그대로 쓰면 코드가 노란색이 아니다.

위에 코드들을 보면 노랑색으로 활성화된 코드들은 JavaScript에서 제공하는 코드이다.

그런데 objectmongoose코드에서만 사용 할수 있다.

그래서 이런식으로 작성할수가 있다.

ower: { type: mongoose.Schema.Types.ObjectId, reqired: true, ref: "User" },
그리고 required: true를 추가해준다. reference도 추가해줄 필요가 있는데

그 이유는 mongoose에게 ownerid를 저장하겠다고 알려줘야 하기 때문이다.

그런데 아직 어떤 model과 연결할지 알려주지도 않은 상태이다.

수많은 model이 있으면 어떤 것과 연결할 것인지 알려줘야 한다.

그래서 mongoose에게 이 owner가 어떤 modelobject라고 알려준다.

여기서는 User model이 된다. 그래서 "User"이라고 넣어 주었다.

이제 video에 owner 항목이 추가 되었다.

ownerobject ID이다. object ID는 여기 보이는 긴 string이다.

ObjectId("626a5e7f2a8175076f7a1e45"

이게 바로 object ID이다.

여기에서 중요한건 Mongoose에게 이 object IDmodel user에서 온다고 알려주는거다.

이렇게 해야 Mongoose가 도와 줄수 있다.

이제 github로그인을 통해 계정을 생성해 준다.

그리고 영상을 하나 업로드 해주기 전에 controller에 수정해줄 부분이 있다.

이제 영상을 업로드 할때 업로드 하는 사용자의 id를 전송해야 하기 때문이다.

videoController.js에서

postUpload controlleruser관련 코드를 추가 한다.

export const postUpload = async (req, res) => {
  const {
    user: { _id },
  } = req.session;
  const { path: fileUrl } = req.file;
  const { title, description, hashtags } = req.body;
  try {
    await Video.create({
      title,
      description,
      fileUrl,
      owner: _id,
      hashtags: Video.formatHashtags(hashtags),
    });

userreq.session에서 가져오면 된다. 그리고 user에서 _id를 가져온다.

그리고 Video를 생성할때 owner도 보내도록 만들어 준다.

Video.create()는 자주 다뤄 봐서 익숙하다. mongoosecreatesave 같은거 말이다.

video modelobject ID type을 가진 owner property를 추가 했다.

그래서 owner_id만 써주면 된다.

user object전체를 전송할 필요는 없고 id만 전송해주면 되는 거다.

이제 다시 영상을 선택해주고 업로드까지 해준다. 영상 재생까지 잘 되는걸 확인 할수 있다.

database도 확인해 본다. db.videos.find({})를 해보면 이제 videoowner가 추가 된걸 알수 있다.

ownerObjectId이다.

성공적으로 model들을 user와 연결 시켰다. 현재는 그렇게 대단하게 보이지 않지만

populate를 배우게 되는 순간부터는 달라 질거다.

populate가 왜 중요한지에 대해 알아 보겠다.

그 이유는 populate가 있어야 영상 주인만 아래 버튼이 보이기 때문이다.

(Edit VideoDelete Video 버튼을 말한다. )

그리고 여기에 누가 올렸는지 보여줄 수도 있다.

일단 버튼을 숨기는 기능을 구현해 보도록 한다.

videoownerid가 있다. 그리고 localMiddleware에 현재 로그인된 사용자가 누구인지 알려주는 부분이 있다.

이 말은 로그인된 사람의 id와 영상의 ownerid가 일치 하면 로그인된 사용자가 현재 영상의 주인이라는 말이다.

template을 수정해 본다. watch.pug를 열고

extends base

block content
   video(src="/" + video.fileUrl,controls)
   div
      p=video.description
      small=video.createdAt 
      small=video.owner
      br
      small=loggedInUser._id 
   a(href=`${video.id}/edit`) Edit Video →
   br
   a(href=`${video.id}/delete`) Delete Video →

id가 일치하는지 체크해준다. 붙어 있으면 일치하는지 헷갈릴수 있으니 띄워 준다.

이렇게 해주면 영상 주인과 현재 로그인된 사용자의 id가 일치하는걸 알수 있다.

이런 상황일때 아래 두 버튼이 보이도록 만들어 본다.

extends base

block content
   video(src="/" + video.fileUrl,controls)
   div
      p=video.description
      small=video.createdAt 
   if String(video.owner) === String(loggedInUser._id)   
      a(href=`${video.id}/edit`) Edit Video →
      br
      a(href=`${video.id}/delete`) Delete Video →

if video.owner === loggedInUser._id 이렇게만 해주었을때는 작동을 하지 않는다.

왜냐하면 video.owneridObjectId인데 현재 접속자의 idstring형태의 데이터 이기 때문이다.

그래서 양쪽에 String()을 넣어주었다. 그래서 새로고침 해서 확인해 보면 잘 작동한다.

이제 videoowner를 확인 할수 있게 되었다.

이렇게 useridvideo model에 저장하니까 유용하다.

누가 영상을 업로드 하였는지 확인 할수가 있게 되었다.

video.owner는 string이고 id라는걸 기억하자.

그러나 아직 해결해야 될게 있다. 영상 소유자의 이름을 가져와야 한다.

누가 비디오를 만들었는지 보여주고 그 사람의 프로칠을 볼수 있는 링크를 걸어 줄 수도 있다.

현재 페이지는 watch페이지이다. watch controller를 찾아 본다.

videoController.js에서

export const watch = async (req, res) => {
  const { id } = req.params;
  const video = await Video.findById(id);
  console.log(video);
  if (!video) {
    return res.status(404).render("404", { pageTitle: "Video not found." });
  }
  return res.render("watch", { pageTitle: video.title, video });
};

이곳에서 video를 찾고 있다. videoconsole.log해본다.

새로고침해서 node에서 찾아 보면

{
  meta: { views: 0, rating: 0 },
  _id: new ObjectId("6278c6ea843aa2ab1951cb7a"),
  title: 'code',
  fileUrl: 'uploads/videos/8354fc579bb23fa577b406bccaafe453',
  description: 'codecodecodecodecode',
  hashtags: [ '#code' ],
  owner: new ObjectId("6278ad69eeed5a64dd710d36"),
  createdAt: 2022-05-09T07:46:50.207Z,
  __v: 0
}

이런 정보가 나온다. owner도 보인다. 이 말은 ownerid를 알고 있다는거다.

이렇게 적용해 볼수 있다.

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 });
};

const owner = 그리고 usermodels에서 import한다.

models에서 Userimport를 해준다.

그리고 User.findById(video.owner)를 해준다.

video에는 owner가 있고 이건 userid이다.

그러면 video를 찾고 이걸 가지고 owner도 찾는 거다.

return res.render("watch", { pageTitle: video.title, video, owner }

그래서 owner도 추가해 주었다.

그리고 watch.pug에서

extends base

block content
   video(src="/" + video.fileUrl,controls)
   div
      p=video.description
      small=video.createdAt 
   div 
      small Uploaded by #{owner.name}   
   if String(video.owner) === String(loggedInUser._id)   
      a(href=`${video.id}/edit`) Edit Video →
      br
      a(href=`${video.id}/delete`) Delete Video →
 div 
      small Uploaded by #{owner.name}   

이렇게 추가해 주었다.

이게 가능한 이유는 ownerwatch template으로 보냈기 때문이다.

새로고침을 해주면 비디오를 업로드한 유저의 이름이 나오는걸 확인 할수 있다.

video를 먼저 찾고 owner를 찾는거다. DB에는 2번이나 요청해서 조금 마음에는 안들지만 잘 작동하고 있다.

이게 바로 영상 소유자의 idvideo에 저장하면 좋은 이유이다.

이제 영상을 볼때 owner가 누군지도 알수 있다.

하지만 언제나 더 쉬운 방법이 있기 마련이다. 현재 코드도 직관적이고 좋다.

이보다 더 나은 방법이 있으니 그렇게 시도해 보도록 한다.

DB에 2번이나 요청하는건 별로이기 때문이다.

현재는 영상 소유자의 idvideo에 저장하면 좋은 이유를 기억한다.

먼저 영상 소유주와 현재 접속자의 id를 비교 할수 있다. 현재 id만 비교하고 있다.

또한 영상 소유주의 이름을 보여줄수도 있다.

중요한건 postUpload에서 video를 생성할때 video.owner에 현재 로그인된 사용자의 id를 넣어 주었다는 거다.

req.session.user가 현재 로그인된 사용자를 말한다.

이 말은 videoowner로 현재 로그인 중인 유저의 id를 쓰겠다는 거다.

profile
꿈꾸는 개발자

0개의 댓글