[23.12.08] TIL

yy·2023년 12월 8일

개발일지

목록 보기
55/122

트러블만 있는 TIL

온갖 테이블이 난무하는 가운데 쉽게 해결할 수 있다고 착각한 부분이 있는데 아래와 같다. 테이블의 내용과 연산 내용을 동시에 보여줘야한다는 점이다.


1. avg(star)를 posts, locations, users,comment 테이블 내용과 함께 조회
2. count(comment) 개수를 posts, locations, users,comment 테이블 내용과 함께 조회



게시글 작성시 locations에 있는 starAvg에 값을 연산해서 넣어주려고 했는데 문제는 게시글 작성한 사람이 입력한 star값을 starAvg에 입력이 안된다는 점이었다. 왜냐면 locations 테이블에 데이터를 우선 입력 후 posts의 데이터가 입력이 되어야했기때문이다.

과연 어떻게 별점 구현할 수 있을까? 레퍼런스를 좀 찾아봐야겠다.


/* 게시물 작성 */
router.post("/posts", authMiddleware, upload.array("imgUrl", 5), async (req, res, next) => {
  try {
    const validation = await createPosts.validateAsync(req.body);
    const {
      content, likeCount, categoryName, storeName, address, latitude, longitude, star } = validation;
    const { nickname } = req.user;

    const user = await prisma.users.findFirst({
      where: { nickname },
    });

    if (!user) {
      return res.status(400).json({ message: "유저가 존재하지 않습니다." });
    }

    const category = await prisma.categories.findFirst({
      where: { categoryName },
    });

    if (!category) {
      return res.status(400).json({ message: "카테고리가 존재하지 않습니다." });
    }

    const districtName = address.split(" ")[1];

    const district = await prisma.districts.findFirst({
      where: { districtName }
    });

    if (!district) {
      return res.status(400).json({ message: "지역이 존재하지 않습니다." });
    }

    //이미지 이름 나눠서 저장
    const imgPromises = req.files.map(async (file) => {
      const imgName = randomImgName();

      const params = {
        Bucket: bucketName,
        Key: imgName,
        Body: file.buffer,
        ContentType: file.mimetype,
      };
      const command = new PutObjectCommand(params);
      await s3.send(command);

      return imgName;
    });

    const imgNames = await Promise.all(imgPromises);

    const location = await prisma.locations.findFirst({
      where: { address }
    });

    const starAvg = await prisma.$queryRaw`select avg(star) as starAvg from Posts where ${location.locationId} groupBy ${location.address}`



    const postsCount = await prisma.posts.aggregate({
      _count: {
        _all: true
      }
    })

    console.log(`별점 평균 : ${starAvg}`)
    // console.log(`postsCount : ${postsCount}`)


    //트랜잭션 일괄처리 필요
    const createLocation = await prisma.locations.create({
      data: {
        storeName,
        address,
        latitude,
        longitude,
        starAvg: 1,
        Category: { connect: { categoryId: +category.categoryId } },
        District: { connect: { districtId: +district.districtId } },
        User: { connect: { userId: +user.userId } }
      },
    });

    const posts = await prisma.posts.create({
      data: {
        content,
        likeCount: +likeCount,
        star,
        User: { connect: { userId: +user.userId } },
        Category: { connect: { categoryId: +category.categoryId } },
        Location: { connect: { locationId: +createLocation.locationId } },
        imgUrl: imgNames.join(","),
      },
    });

    return res.status(200).json({ posts });
  } catch (error) {
    console.log(error)
    next(error);
  }
});
profile
시간이 걸릴 뿐 내가 못할 건 없다.

0개의 댓글