-
[sequelize] 관계(Associations)에 따른 method 요약과 생긴 에러공부 2022. 9. 28. 18:41
혼자서 공부를 하다 Node.js를 사용하여 MySQL에 데이터를 넘겨줘야 하는 일이 생겼다. 내가 구현하고자 했던 것은 Like 버튼을 누르면 해당 게시물에 Like에 불빛이 켜지며, MySQL에 어떤 유저가 어떤 글에 좋아요를 한 것인지 저장을 해줘야 한다.
중요한 것은 나는 MySQL을 사용해보지 않았기 때문에 문법이 익숙치 않았다.
그래서 Sequelize를 사용하여 js코드를 MySQL 코드로 바꿔주는 방법을 택했다.
또한 Sequelize도 처음 사용해봐서 오타를 내거나 중요한 것을 빼먹거나 그러한 일이 빈번히 일어났다.
이 글을 작성하게 된 이유도 나의 실수로 인한 분법 오류를 다시 일으키지 않기 위해서이다.
Sequelize
Sequelize를 간단하게 설명하자면 모델간의 관계를 작성할 때 JavaScript로 작성할 수 있게 도와주는 라이브러리이다.
모델 간 관계를 설정하기 위해 Sequelize에서 제공하는 method는 총 4가지가 있다.
- BelongsToMany
- BelongsTo
- HasMany
- HasOne
이 글에서는 Sequelize에 대해서 설명하는 글이 아니기 때문에 내가 사용한 BelonsToMany에 대해서만 작성할 것이며 , 추후에 Sequelize에 대해서 다시 작성할 것이다.
먼저 Sequelize는 비동기 함수이며, Promise를 반환하는 함수이다.
나는 belongsToMany를 사용하여 User와 Post의 관계를 설정했으며, 중복을 피하기 위해 as를 사용해서 관계를 설정해줬다.
과정
먼저 게시글을 Like를 하기 위해서는 유저의 정보가 있어야 한다. 즉 로그인을 하면 passport라이브러리로 인하여 유저의 정보가 req.user.id에 저장되어 있다.
그리고 로그인된 사용자가 게시글을 누르면 해당 게시글의 ID가 넘어와 MySQL에 저장된 게시글 중 동일한 ID를 찾은 뒤 해당 게시글에 ID와 사용자의 ID를 MySQL에 저장해준다.
에러
코드를 작성한 뒤 나에게는 총 2가지 에러가 발생했다.
- id is undefined
- addLikes is not a function
먼저 req.user.id에 사용자의 ID가 저장되어 있는데 어떨 때는 ID가 1번 에러가 뜨고 어떨때는 2번 에러가 뜨는 것이다. 그래서 나는 1번에러가 발생한 것을 먼저 해결하기 위해서 원인을 찾기 시작했다.
하지만 모든 코드를 확인해보았는데 이상이 없었다. 그래서 이건 코드 문제가 아니라 서버쪽에서 뭔가 이상하다고 느꼈고, 나머지 기능들을 다 사용했는데 정상적으로 작동되던 기능들도 유일하게 에러가 나는 경우가 있었다.
로그인을 안했을 때!!!
내가 관과했던 것이다. 코드를 수정하면 서버가 알아서 재실행되기 때문에 현재 내 서버의 유저 상태는 로그인을 하지 않은 상태이지만 내가 보고 있는 페이지는 새로고침을 하지 않았기 때문에 로그인이 된 것처럼 보인 것이었다.
이를 알아차리고 난 뒤부터 1번 에러는 볼일이 없어졌다. 이제 두번째 에러를 해결해야 한다.
나는 여러 게시글들 중 받은 게시글의 ID랑 동일한 ID를 MySQL에서 찾아야 하기 때문에 Sequelize에서 제공하는 findOne이라는 메서드를 사용하였다. findOne은 비동기 함수이며 Promise를 반환하게 된다. 그래서 나는 post라는 변수에 findOne이 반환하는 값을 저장한 뒤 출력해보았는데 null이 뜨고 있었다.
null이 발생한 경우는 해당 게시물이 없을 때 발생하는 것인데 나는 MySQL과 받은 데이터를 확인해 보았는데 모두 정보가 담겨있었다. 근대 findOne함수를 거치면 null을 반환하는 것이었다.
나는 Sequelize를 처음 사용해보았기 때문에 공식문서를 읽으면서 시작했고, 원인을 찾아버렸다.
async findOne(options: object):Promise <Model | null>
공식문서에 적혀있는 것이다. 하지만 나는 비동기 함수인 것을 까먹고있었고, await을 빼서 작성한것이였다. 그래서 await를 붙인 뒤 출력을 해보니 정상적으로 Promise를 반환하기 시작했다. (여기서 제일 화가났다)
나는 이 에러를 해결한 뒤 이제 작동되겠지 하고 실행을 해보았는데 이번에는 다른 에러가 발생했는데 req.params.id에 오브젝트로 데이터가 두 개가 존재한다는 것이다.
나는 분명히 ID를 받아 받은 것을 통해 MySQL에 저장하고 프런트 쪽으로 결과를 반환하는데 갑자기 ID가 오브젝트라니,,,
나는 서버로 데이터를 전달하는 Redux-saga에서 전달을 잘못해주나라고 생각하고 Redux-saga코드를 확인해보았다. 확인해보니 dispatch를 할 때 action.data에는 type과 data가 담겨있는데 나는 이 action.data를 바로 서버에 넘겨줬던 것이다. 그래서 이 실수는 빠르게 찾아 type을 빼고 data만 서버 쪽으로 넘겨주니 지금까지 발생했던 에러가 모두 사라졌다.
후기
처음 배우고 사용하는 것 때문에 많은 어려움이 있었는데 이번 일을 통해서 나는 공식문서를 읽는 것 능력이 많이 향상되었다고 생각한다.
물론 다른 점도 있지만 이전까지는 영어로 된 공식문서를 읽는 것을 좋아하지는 않았지만 이번 일을 계기로 영어로 된 공식문서에 조금 고마움을 느꼈다.
'공부' 카테고리의 다른 글
기기에 따른 페이지의 높이 조절 (0) 2022.12.14 CRP - Critical Rendering Path (1) 2022.12.11 next-redux-wrapper의 getServerSideProps (0) 2022.10.11 무한스크롤 (0) 2022.09.15 eslint를 추가한 뒤 styled-component에서 에러가 발생했다. (0) 2022.09.05