개발일지

개발일지 53일차

index.ys 2023. 5. 17. 04:36

에러

- 팔로우 추가 기능구현시 내가 팔로우한 사람의 목록을 전체 조회 했을때 팔로우 한 사람의 프로필 이미지와 이름이 뜨지 않고 로그인된 사람의 프로필 사진과 이름이 뜨는 에러발생

팔로우에 추가한 전체 인원을 조회 하기 위해 시도 방법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를 받을 수 없음