일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- flask
- async
- SAA
- 중급파이썬
- socket io
- crud
- SSA
- 튜플
- Props
- 카톡
- EC2
- 파이썬
- lambda
- NeXT
- MongoDB
- docker
- git
- RDS
- dict
- 채팅
- AWS
- Class
- S3
- Vue
- react
- pandas
- TypeScript
- wetube
- merge
- node
- Today
- Total
초보 개발자
Model populate, bug fix ( ★★★ ) 본문
이번에 해볼 것은
User의 model 속에 Video의 id들(여러개)을 집어넣어 자기가 올린 영상을 추적할 수 있도록 한다. 반대로
Video의 model 속에 User의 id를(한개) 집어넣어 이 영상을 올린 주인을 추적할 수 있도록 한다.
mongoose는 정말 편리한 것 같다!!!
각 model들은 생성될 때 고유의 id를 하나씩 가지고 태어난다. 지금은 서로 User모델과 Video 모델이 연결되어있지 않지만 고유한 id값을 이용하면 된다.
User.js
type이 특이하다. id값을 이용하기 위하여 ObjectId로 설정해줘야 한다.
ObjectId만 적어주면 안되고 꼭 저렇게 설정해야한다. 그리고 우리가 참조할 Model을 ref명령어를 통해서
적어주어야하는데 우리는 저 videos에 Video모델들을 집어 넣을 것이니까 Video라고 해준다.
그리고 한 유저는 여러개의 video를 올릴 수 있으니까 videos를 배열로 만들어 주었다.
즉 videos는 Video model에 연결된 ObjectId로 구성된 array이다
Video.js
owner를 추가해주고 type은 아까와 마찬가지로 지정해주었다. 이번에는 required: true를 주었는데.
유저가 영상을 반드시 올려야 하진 않지만 동영상은 반드시 누군가에 의해 올려지기 때문이다. User의 id값을 넣기에 ref를 User로 지정해주었다.
이렇게 해주면 참 편하다. 손이 두번가는걸 한번에 해결할 수 있다.
먼저 postUpload에 가보겠다.
빨간 부분이 추가가 되었다.
먼저 session을 통해 로그인 되어있는 유저의 id값을 가져와서 Video model을 생성할 때 추가해 주었다.
여기서 끝내는 것이 아니라 User에도 추가해 줘야 하기 때문에 아까 가져온 id를 통해서 업로드 하고 있는 user의 정보를 가져온후 이번엔 video의 id값을 videos에 추가하여 저장해주었다.
모든 것이 잘 저장되었지만 user.save()를 하게되면 예상치 못한 곳에 문제가 생긴다. 이 부분은 마지막에 설명하겠다.
이렇게 되면 Video와 User에 둘 다 각자의 id를 가지고 있는 상태이다.
이를 통해 다양한 것이 가능하다. 먼저 video의 getEdit handler를 살펴보자.
video를 edit하려고 할때 우리가 미들웨어로 로그인의 유무만 따졌기 때문에 설령 내가 이 동영상을 올린사람이 아니더라도 수정하거나 지우는게 가능하다. 이러면 무슨 소용인가? 작성자만 접근 가능해야 할 것이다.
여기서 populate('owner')를 사용할 수 있는데 우리가 upload할 때 owner에 User의 id를 넣었 던 적이 있다.
또 mongoose는 owner가 objectId인것을알고 그 id가 User에서 온 것임 을안다.
우리는 분명 id만 저장했는데 populate를 통해 몽구스가 그 아이디를 추적하여 값들을 가져온다. video를 출력해보면
owner에 원래는 ObjectId가 들어있는데 populate를 통하여 그 Id가 가지고있는 정보를 가져온 것이다. 이를 통해 작성자의 정보또한 가져올 수 있는 것이다.
이를 통해서 현재 세션에 로그인 되어 있는 id와 video의 owner의 id를 비교하여 같다면 현재 작성자가 로그인 해있다는 것을 알 수 있고 이 경우에만 edit이 가능하도록 해주었다.
postEdit과 delete또한 같은 방식으로 하였다. 다만 delete를 할 때는 한가지 생각해 보아야 할 것이 있다.
강의에서는 설명을 안해주었지만 User에 남아있는 videos의 기록은 지워지지 않기에 이 부분 또한 고려를 해줘야 한다고 생각하였다.
user의 값을 가져온 뒤 user.videos에 현재 지우려는 video의 id값을 indexOf로 index를 찾은 뒤 splice를 통하여 지워주는 방식을 사용하였다. 그 뒤에 save()까지 잊어주면 안된다!!! 이렇게 해주면 video도 없어지고 user.videos에서도 없어지는 것을 알 수 있다.!!
watch에서 기존에는 populate를 하지 않은 video의 값을 넘겨주었지만 populate을 한 뒤 넘겨주면
영상에서 누가 올린지 명시해 줄 수 있다.
또한 Edit Video와 Delete Video 버튼?또한 작성자가 아니면 보이지 않도록 설정까지 해줄 수 있다.
이번엔 user에 있는 videos를 활용하여 user가 올린 video들을 볼 수 있는 hompage를 만들어보겠다.
see.pug
mixin을통해 간단하게만 보여주겠다.
router를 추가하여 user의 id를타고 들어갈 수있는 homepage이다
see handler
id를 통해서 user의 id를 받아 온 뒤 populate('video')를 하여 작성자가 올린 비디오 데이터를 전부 가져올 수 있게한다.
그리고 그 videos를 pug에 넘겨주어 페이지에 나타나게 할 수 있다.
자 이제 위에서 말 했던 user.save를 사용하면 생기는 문제점에 대해서 이야기 해보겠다.
로그아웃 한 뒤 다시 로그인을 해보면 어떻게 될까? 갑자기 비밀번호가 다르다고 나온다. 왜일까??
우리는 userSchema, postUpload handler에서 아래와 같은 작업을 해주었다.
user.save()를 하면 save되기 전 password가 다시한번 해쉬되어 기존 password로는 이제 로그인이 되지 않는다.
this.isModified('password')
이럴 겨웅 isModified라는 걸 사용하면 되는데 뒤의 인자에 오는 schema가 변경이 되었다면 true를 아니라면 false를 반환한다. 이런 작업을 통하여 password가 수정되지 않았을 때는 해쉬 되지 않도록 해주는 것이다.
전에 change-pw를 해볼 때는 이 부분을 고려해주지 않았는데 어처피 새로운(해쉬 되지 않은) 비밀번호를 저장하기 때문에 hash를 해주는 거라서 따로 신경을 안써주어도 된다.
const video = await Video.findById(id)
video.id // String
video._id // Object
const user = await User.findById(id)
user.videos.push(video.id)
user.videos.push(video._id)
둘다 상관 없는 듯
loggedUser.id X
loggedUser._id O < String
video.owner < ObjectId
loggedUser._id 와 비교하려면 String(video.owner)로 해주어야 됨
버그 fix를하면서 물이 새는 곳에 납땜질하는 것과 같다는 생각이 들었다 ㅋㅋ
'RECAP - WETUBE' 카테고리의 다른 글
Video player (0) | 2021.10.05 |
---|---|
Webpack loader (0) | 2021.10.02 |
avatar , video upload (multer, static) (0) | 2021.09.29 |
middleware / edit, change-pw handler (★★★) (0) | 2021.09.28 |
Github Login - oAuth 2 (0) | 2021.09.28 |