개발일지 40일차
2주차 시험 오답풀이
- GET /posts/like API 내부에서 함수 표현식을 이용해 호이스팅을 발생시켜 오류 출력하기
- 함수 표현식을 이용해 변수에 함수를 할당할 경우 발생하는 호이스팅 문제점을 인지해야한다.
수정전
router.get('/like', authMiddleware, async (req, res) => {
try {
const { userId } = res.locals.user;
const posts = await Posts.findAll({
attributes: [
'postId',
'title',
'createdAt',
'updatedAt',
[sequelize.fn('COUNT', sequelize.col('Likes.PostId')), 'likes'],
],
include: [
{
model: Users,
attributes: ['userId', 'nickname'],
},
{
model: Likes,
attributes: [],
required: true,
where: {
[Op.and]: [{ UserId: userId }],
},
},
],
group: ['Posts.postId'],
order: [['createdAt', 'DESC']],
raw: true,
}).then((likes) => parseLikePostsModel(likes));
// Like와 Post모델을 Join한 결과를 Plat Object로 변환하는 함수
const parseLikePostsModel = (likes) => {
return likes.map((like) => {
let obj = {};
for (const [k, v] of Object.entries(like)) {
if (k.split('.').length > 1) {
const key = k.split('.')[1];
obj[key] = v;
} else obj[k] = v;
}
return obj;
})
}
return res.status(200).json({
data: posts,
});
} catch (error) {
console.error(`${req.method} ${req.originalUrl} : ${error.message}`);
console.error(error);
return res.status(400).json({
errorMessage: '좋아요 게시글 조회에 실패하였습니다.',
});
}
});
수정후
- parseLikePostsModel함수의 호출부가 선언부 보다 위에있어 함수의 선언부를 호출부 위로 끌어올려주는 수정을 했어야했다.
router.get('/like', authMiddleware, async (req, res) => {
try {
const { userId } = res.locals.user;
// Like와 Post모델을 Join한 결과를 Plat Object로 변환하는 함수
const parseLikePostsModel = (likes) => {
return likes.map((like) => {
let obj = {};
for (const [k, v] of Object.entries(like)) {
if (k.split('.').length > 1) {
const key = k.split('.')[1];
obj[key] = v;
} else obj[k] = v;
}
return obj;
})
}
const posts = await Posts.findAll({
attributes: [
'postId',
'title',
'createdAt',
'updatedAt',
[sequelize.fn('COUNT', sequelize.col('Likes.PostId')), 'likes'],
],
include: [
{
model: Users,
attributes: ['userId', 'nickname'],
},
{
model: Likes,
attributes: [],
required: true,
where: {
[Op.and]: [{ UserId: userId }],
},
},
],
group: ['Posts.postId'],
order: [['createdAt', 'DESC']],
raw: true,
}).then((likes) => parseLikePostsModel(likes));
return res.status(200).json({
data: posts,
});
} catch (error) {
console.error(`${req.method} ${req.originalUrl} : ${error.message}`);
console.error(error);
return res.status(400).json({
errorMessage: '좋아요 게시글 조회에 실패하였습니다.',
});
}
});
lv4과제
- db에 migrate하기
npx sequelize db:migrate
- db에 migrate 되돌리기
npx sequelize db:migrate:undo
- model파일 생성하기
npx sequelize model:generate --name Posts --attributes title:string,content:string,password:string
app.js 수정
- router를 좀 더 효율적으로 처리하기 위해 공통된 경로끼리 묶어주고 아닌 경로를 따로 나눠주는 처리를 하였다.
app.use(express.json());
app.use(cookieParser());
app.use('/posts', [likeRouter, postsRouter, commentRouter, authRouter]);
app.use('/', authRouter);
Posts.js Model 작성
- targetKey:참조 되는 키
- sourceKey: 소스 키
- foreingnKey: 외래 키 ,다른 테이블에 특정 키를 참조
soureceKey와 targetKey는 동일해야하고, foreignKey는 참조하는쪽과 참조 되는쪽이 동일해야한다.
static associate(models) {
this.hasMany(models.Posts, {
sourceKey: 'userId',
foreignKey: 'UserId',
});
this.hasMany(models.Likes, {
sourceKey: 'userId',
foreignKey: 'UserId',
});
this.hasMany(models.Comments, {
sourceKey: 'userId',
foreignKey: 'UserId',
});
Usres.js Model 작성
static associate(models) {
this.belongsTo(models.Users, {
targetKey: 'userId',
foreignKey: 'UserId',
onDelete: 'CASCADE',
});
this.hasMany(models.Likes, {
sourceKey: 'postId',
foreignKey: 'PostId',
});
this.hasMany(models.Comments, {
sourceKey: 'postId',
foreignKey: 'PostId',
});
관계설정
- hasMany: 1: n 관계에서 참조하는 테이블이 되는 쪽에 설정해줌
- belonsTo: 참조받는 테이블에서 설정
Migration 관리방법
- migration파일을 날짜별로 관리한다. migration파일은 결국 현재 db상태를 업데이트, 다음 업데이트에서는 어떤 상태로 변경할 것인지를 의미
- 하나의 db를 사용함, 실제 서비스 개발시 실제고객이 사용하는 db와 개발,테스트용 db로 나누어져 사용
- 개발용 db는 실수하면 밀어버리고 재생성이 가능하지만, 서비스용 데이터는 실제고객이 사용하고 있기때문에 삭제 불가,
그렇기 때문에 migration파일을 날짜별, 버전별로 수정해야함
Model 파일
- model은 서버에서 db를 어떻게 바라보는지 설정, db와 서버는 완전히 다른 개체이기때문에 서버가 db를 이해하기 위한 수단중 하나가 ORM을 이용해 이해하는 방법, migration은 db셋팅도 서버에서 할 수 있게 도와주는 요소
- model은 db를 서버와 실제로 이어주는 역할(ORM), migration은 db셋팅의 역할
오늘 생성한 users데이터
에러처리
- 과제의 단계가 오르면 오를수록, 코드의 길이가 길어지면 길어질수록 에러가 자주뜬다 에러를 자주보다 보면 공통적인
에러들이 자주 발생한다. 그게 아니더라도 에러를 자세히 읽어보면 대부분 어느부분에서 에러가 발생되었는지 확인할 수 있다는걸 느꼈다
오늘 발생한 에러들
- 미들웨어 정의오류
- 오타
- 에러는 아니지만 db에 설정된 컬럼의 값이 들어가지 않아 db를 drop하고 migration파일을 수정한다음에 다시 db를 생성해주었다.
- 기타오류
db에 수정할 내용이 생기면 db를 drop하는 방법말고, migration파일을 이용해 수정하는 방법을 연습해야겠다 sql을 이용한 방법이나 cli를 이용하여 db를 수정하는 방법을 사용하고 날짜별로 migration파일을 관리하는 방법의 필요성을 느꼈다.