에러
- 팔로우 추가 기능구현시 내가 팔로우한 사람의 목록을 전체 조회 했을때 팔로우 한 사람의 프로필 이미지와 이름이 뜨지 않고 로그인된 사람의 프로필 사진과 이름이 뜨는 에러발생
팔로우에 추가한 전체 인원을 조회 하기 위해 시도 방법1
- repository 계층에서 findAll메소드를 사용하고 where절로 조건을걸음 현재 로그인한 사람의 user_id 전달받아 로그인한 사람이 팔로우를 추가한 사람의 목록을 follows 모델에 접근하여 조회함
- include속성으로 Users모델과 attributes로 참조할 컬럼을 지정함
- Follows 모델에서 참조할 속성을 attriutes로 지정함
getFollowerAll = async (user_id) => {
const findAllPostsData = await this.Follows.findAll({
where: { user_id },
include: [
{
model: Users,
attributes: ["profile_url"],
require: true,
},
],
attributes: [
"follow_id",
"user_id",
"follower_user_id",
"createdAt",
"updatedAt",
]
});
return findAllPostsData;
}
분기처리
postFollower = async (user_id, follower_user_id) => {
try {
const findFollower = await this.followerRepository.findFollower(user_id, follower_user_id)
if (findFollower) {
return { message: "이미 추가된 팔로워 입니다" };
} else {
await this.followerRepository.postFollower(
user_id,
follower_user_id
);
return { message: "팔로워 추가 완료" };
}
} catch (error) {
console.error(error)
}
문제
- Follows 모델에서 참조한 follower_user_id가 Users 모델에서 user_id와 같은 값을 찾아야하는데 그렇다면 include전에
- Users모델에 먼저 findAll 메소드로 접근해야해서 다른 방식으로 변경함
팔로우에 추가한 전체 인원을 조회 하기 위해 시도 방법2
- Follows 모델에 findOne메소드를 사용하여 user_id에 해당하는 값들만 전부조회함
getFollowerAll = async (user_id) => {
const findAllPostsData = await this.Follows.findOne({
where: { user_id }, //3
attributes: ["follower_user_id", "createdAt", "updatedAt"], //7
order: [["createdAt", "DESC"]]
});
const recentFollowerId = findAllPostsData.dataValues.follower_user_id
const findAllUsersData = await this.Users.findOne({
where: { user_id: recentFollowerId },//7
attributes: ["user_id", "name", "profile_url"]
})
return findAllUsersData;
}
문제
- findOne메소드를 사용하면 최근에 추가된 팔로워 전체가 아닌 한명만 조회하게되는 문제 발생
팔로우에 추가한 전체 인원을 조회 하기 위해 시도 방법3
- Follows 모델에 먼저 접근하여 현재 로그인한 아이디에 해당하는 팔로워들을 조회하고 참조하려는 값을 지정함
- 받아온값(배열)중 follower_user_id의 값만 받아오기 위해 새로운 변수에 follower_user_id 값만할당함
- 받아온 follower_user_id에 해당하는 user_id를 Users 모델에서 조회함
getFollowerAll = async (user_id) => {
const findAllPostsData = await this.Follows.findAllPostsData({
where: { user_id }, //3
attributes: ["follower_user_id", "createdAt", "updatedAt"], //7
order: [["createdAt", "DESC"]]
});
const recentFollowerId = findAllPostsData.dataValues.follower_user_id
const findAllUsersData = await this.Users.findOne({
where: { user_id: recentFollowerId },//7
attributes: ["user_id", "name", "profile_url"]
})
return findAllUsersData;
}
팔로우에 추가한 전체 인원을 조회 하기 위해 시도 방법4
service 계층
getFollowerAll = async (user_id) => {
const getUserData = await this.followerRepository.getFollowerAll(user_id)//3
return getUserData.map(e => {
return {
user_id: e.Users.dataValues.user_id,
name: e.Users.dataValues.name,
profile_url: e.Users.dataValues.profile_url,
};
})
};
repsitory 계층
findFollower = async (user_id, follower_user_id) => {
const postFollowData = await this.Follows.findOne({
where: {
user_id: user_id,
follower_user_id: follower_user_id,
}
});
return postFollowData;
};
추천받은 코드
- sql쿼리문을 기반으로 sequelize 문법을 작성했다
SELECT U1.user_id AS my_user_id, U1.nickname AS my_nickname, U2.user_id AS fl_user_id, U2.nickname AS fl_nickname, U2.url AS fl_url
FROM Users U1
JOIN Follows F ON U1.user_id = F.my_user_id
JOIN Users U2 ON U2.user_id = F.fl_user_id;
- 내가 작성한건 아니고 다른 조원에 계시는 분이 내가 설명드렸던 로직을 기반으로 쿼리를 작성해 주셨다.
- include 문법을 사용해 follow모델과 users모델을 한번씩 조인하는 문법을 작성해주셨다. 현재 로직에 적용을 해보진 못했지만 sequlize 문법을 sql 다시 변환해보는 연습도 중요하다고 느꼈다.
const result = await Users.findAll({
attributes: [
[sequelize.col('U1.user_id'), 'my_user_id'],
[sequelize.col('U1.nickname'), 'my_nickname'],
[sequelize.col('U2.user_id'), 'fl_user_id'],
[sequelize.col('U2.nickname'), 'fl_nickname'],
[sequelize.col('U2.url'), 'fl_url'],
],
include: [
{
model: Follows,
as: 'Follow',
attributes: [],
include: [
{
model: Users,
as: 'User2',
attributes: [],
where: {},
required: true,
},
],
where: {},
required: true,
},
],
});
현재 적용된 코드
serviece 계층
- repository에서 전달받은 user의 데이터를 가공함
getFollowerAll = async (user_id) => {
const getUserData = await this.followerRepository.getFollowerAll(user_id)
const a = getUserData[0].map((e) => {
return {
follow_id: e.dataValues.follow_id,
createdAt: e.dataValues.createdAt,
updatedAt: e.dataValues.updatedAt
}
})
const b = getUserData[1].map((e) => {
return {
user_id: e.dataValues.user_id,
follower_name: e.dataValues.name,
profile_url: e.dataValues.profile_url
}
})
let jujimin = [];
for (let i = 0; i < a.length; i++) {
let c = { ...a[i], ...b[i] };
jujimin.push(c);
}
return jujimin
};
repository 계층
- findAll 메소드로 현재 로그인한 id에 해당하는 값을 전부 조회
- 조회한 데이터중에서 follower_user_id값만 변수에 선언
- users 모델에서 user_id: followUserIds에 해당하는 조건의 값들을 조회
- 조회한 값을 return
getFollowerAll = async (user_id) => {
const followList = await this.Follows.findAll({
where: { user_id },
});
const followUserIds = followList.map((e) => e.follower_user_id);
const userInfos = await this.Users.findAll({
where: {
user_id: {
[Op.in]: followUserIds,
},
},
});
return [followList, userInfos]
}
바꿀 수 있을거 같은 부분
- 현재 적용되어 있는 repository 계층에서 1번의 요청에 users 모델과 follows에 각각 접근하여 데이터를 조회하고 데이터를 조인하는 로직을 작성 할 수 있을거 같다는 생각이 들었다.
- service 계층에 작성된 반복문들을 repository 계층에서 쿼리문으로 줄일 수 있을 거라는 생각이 들었다.
꿀팁
- api요청시 get요청과 delete 요청은 요청값으로 body를 받을 수 없음