Edit Video # 03

0_CyberLover_0·2022년 4월 13일
0

Node.JS # 03

목록 보기
16/19

이전 파트에서 마무리 짓지 못했던 걸 이어서 해보도록 하겠다.

그러기 위해서 먼저 findOneAndUpdate()라는 function에 대해 배워 볼거다.

https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate

실제로 model에는 할수 있는게 굉장히 많다.

여러가지 들이 있는데 이것들의 차이점은 뭐냐면 예를 들어 findOne을 보면

어떤 조건이든 지정할수가 있다. 제목이 Hello인 영상을 하나 검색 할 수도 있다.

다른 말로는 영상 제목으로 검색 할수 있다는 말이다.

하지만 영상을 ID로만 찾을 거란걸 미리 알고 있다면 findOne을 쓸 필요가 없다.

그냥 findById를 쓰면 된다. 그리고 이미 준비 되어 있다.

findByIdAndUpdate()도 있다. 지금 상황에 딱 필요 한거다.

지금 해야 하는 것은 영상의 ID를 여기 findByIdAndUpdate()에 입력 하면 된다.

그러면 이제 귀찮게 일일이 수정하는 대신

videoController.js에서

export const postEdit = async (req, res) => {
  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." });
  }
  await Video.findByIdAndUpdate(id, {
    title,
    description,
    hashtags: hashtags
      .split(",")
      .map((word) => (word.startsWith("#") ? word : `#${word}`)),
  });
  return res.redirect(`/videos/${id}`);
};

await Video.findByIdAndUpdate() 이라고 하면 된다.

findByIdAndUpdate()은 두개의 인수 (argument)가 필요하다.

하나는 업데이트 하고자 하는 영상의 ID이다. 그 ID는 바로 위에 있다.

그러니까 id라고 입력 하고 두번째 인수는 업데이트 할 정보 혹은 내용이다.

그래서 위에 처럼 입력 하게 되었다. hashtags만 조금 다르다.

이제 코드를 테스트 해보고 아무 문제 없으면 다음으로 넘어 가도록 한다. 잘 작동한다.

두가지 옵션을 배웠다.

하나는 일단 데이터 베이스에서 영상을 찾은후에 수동으로 video.title = something

이런 식으로 수정하는 방법이였다.

다른 방법은 Mongoose에서 제공하는 function을 쓰는 거다.

Video는 사용되는 model이고 findByIdAndUpdate() 아주 큰 차이가 있다.

대문자 Vvideo는 만든 영상 Model이다.

소문자 vvideodatabase에서 검색한 영상 object이다.

Model이기 때문에 이곳에 있는 모든 것들을 쓸수 있다.

https://mongoosejs.com/docs/api/model.html

그 중에 exists()를 살펴 본다.

exists() 굉장히 유용하다. 예를 들어

  export const postEdit = async (req, res) => {
  const { id } = req.params;
  const { title, description, hashtags } = req.body;
  const video = await Video.findById(id);

이곳을 보면 영상이 존재하는지 확인해야 한다. 꼭 굳이 video object를 가져올 필요까지는 없다.

  const video = await Video.findById(id);

지금까지 video object 전체를 항상 검색하였다. 왜냐하면 video.title = blabla

이렇게 수정하려면 전체가 다 필요 했기 때문이다. 지금은 video object 전체가 필요 하지 않다.

findById()대신에 exsts()를 써 줄수 있다. 그럼 exists()turereturn하게 된다.

영상이 없을 경우 falsereturn할 것이다.

다시 말하자면 postEdit에서 video를 찾을 필요가 없다.

그래서 exists()로 바꿔 준다.

그리고 exists()ID를 받지 않는다. exists()filter를 받는다.

이 말은 원하는 조건은 아무거나 쓸수 있다는 거다. 그래서 이 경우에는

  const video = await Video.exists({ _id: id });

여기에 조건을 입력할거다. mongodb에서 볼수 있듯 object에는 id가 있다.

(mongodb 에서 db.videos.find()를 입력 하는데 아무 반응이 없길래

알아 봤더니 터미널이 종료 되면 다시 mongo shell안에서 use wetube를 해줘야 한다.)

이제 objectidreq.paramsid와 같은 경우를 찾는다.

한마디로 video object를 받는 대신에 true혹은 false를 받는거다.

이 경우에도 exists()를 쓸수 있을까?

export const getEdit = async (req, res) => {
  const { id } = req.params;
  const video = await Video.findById(id);
  if (!video) {
    return res.render("404", { pageTitle: "Video not found." });
  }
  return res.render("edit", { pageTitle: `Edit ${video.title}`, video });
};

안된다. 왜냐하면 getEdit에서는 video object가 꼭 필요하다.

objectedit template으로 보내줘야 한다. 이 같은 경우에는 exists()를 쓸수가 없다.

하지만 postEdit에서는 video object가 필요 없다.

단순히 영상이 존재하는지만 확인하면 된다. 그리고 exists()같은 경우엔 ID만 받지 않는다.

filter를 받는다. 그래서 제목이 "hello"인 영상의 존재 여부를 알수 있다.

원하는 모든 조건을 입력 할수 있다.

ex:)   const video = await Video.exists({ title: "hello" });

이제 hashtags부분을 알아 본다.

hashtags: hashtags
      .split(",")
      .map((word) => (word.startsWith("#") ? word : `#${word}`)),

생각해야 될게 지금 뭘 하고 싶은지 뭘 하고 있는지 생각해야 한다.

지금 해시태그들을 처리하고 있다. 변경사항을 저장할때마다 혹은 저장하기 직전에

영상 업데이트나 영상 생성을 위해 저장하기 전에 hashtags를 처리하고 있다.

그러니까 저 부분은 Model에 저장하기전에 처리 하는 것들이다.

생각해보면 영상을 저장하기전에 여러가지를 할수 있고 해야만 하는 거다.

예를 들어 코멘트가 있다고 가정해본다. 그리고 그 코멘트를 저장하기전에 비속어를 검색하고 싶다고 가정해 본다.

아니면 사용자를 생성한다고 해본다. 그리고 생성하기전에 e-mail이 존재하는 이메일인지

아닌지 확인한다 던가 그러니깐 저장하기전에 고려해야 할것들이 정말 많다.

hashtag processing은 그냥 예시일 뿐이다. 실제로는 저장 하기전에 뭔가를 하거나 체크를 한다.

복붙하기에 좀 꺼려지는 이유가 왜냐하면 보다시피 영상을 생성하기전에 그리고 영상을 업데이트 하기전에

해시태그를 처리하고 있다.

그래서 Mongoose에는 또 다른 걸 써 볼거다.

영상을 저장, 혹은 업데이트 전에 이거저거 하라고 시키는거다.

그걸 Middleware라고 한다. Express에서 본 Middleware랑 똑같다.

Mongoose에도 Middelware가 있고, pre,post,hook도 있다.

이름은 그렇게 중요한 것이 아니다. 중요한건 그것들이 끼어들 틈을 만들어 준다는 거다.

objcet가 저장 되기전에 무엇인가를 먼저하고 나머질 처리 할수 있게 말이다.

그게 정확하게 지금 하고자 하는 거다.

영상을 생성하거나 업데이트 하기전에 그 프로세스를 잠시 중단하고 hashtags를 처리해서

더 깔끔하게 정리를 하고 그리고 하던걸 마저 하는 거다.

하지만 그건 다음 파트에서 하기로 한다.이번 파트에서는 그냥 몇가지를 알아 본다.

첫번째로 exists()findById같은거다.

exists()는 필터를 필요로 하고 영상의 어떤 property도 필터 가능하다.

하지만 findById는 꼭 id를 인자(argument)로 받는다.

두번째로 영상을 생성하거나 업데이트 하기전에 작동할 function의 필요성에 대한 이해이다.

이 같은 경우

  await Video.findByIdAndUpdate(id, {

functionhashtags를 처리해서 hashtags같이 보이게 하는

hashtags: hashtags
      .split(",")
      .map((word) => (word.startsWith("#") ? word : `#${word}`)),

이부분이 될거다.

profile
꿈꾸는 개발자

0개의 댓글