Backend - Sequelize: M:N 관계일 때 관계 추가하기

BigbrotherShin·2020년 3월 31일
1

Backend

목록 보기
7/15
post-thumbnail
post-custom-banner

Post와 User의 관계 설정

backend/models/post.js

module.exports = (sequelize, DataTypes) => {
  const Post = sequelize.define(
    'Post',
    {
      content: {
        type: DataTypes.TEXT, // 매우 긴 글은 TEXT로
        allowNull: false,
      },
    },
    {
      charset: 'utf8mb4', // 한글 + 이모티콘
      collate: 'utf8mb4_general_ci',
    },
  );

  Post.associate = db => {
    db.Post.belongsTo(db.User);
    // belongsTo가 있는 테이블에 다른 테이블의 id를 저장(Post 테이블에 UserId 저장)
    
    db.Post.belongsToMany(db.User, { through: 'Like', as: 'Likers' });
    // 게시글에 like
  };

  return Post;
};

db.User.belongsToMany(db.Post, { through: 'Like', as: 'Liked' });에서
through는 포함시킬 DB의 table이고,
as는 프론트에 전달할 객체의 key이다.

하단에서 게시글들을 가져올 때 데이터가 어떻게 프론트로 전달되는 지 알아보겠다.

좋아요 추가하기

backend/routes/post.js

router.post('/:id/like', isLoggedIn, async (req, res, next) => {
  try {
    const post = await db.Post.findOne({
      // 보안을 위해 게시글이 존재하는지부터 검사
      where: { id: req.params.id },
    });
    if (!post) {
      return res.status(404).send('포스트를 찾지 못했습니다.');
    }
    await post.addLiker(req.user.id);
    res.json({ userId: req.user.id });
  } catch (e) {
    console.error(e);
    next(e);
  }
});

게시글 가져올 때 좋아요도 가져오기

backend/routes/posts.js

const express = require('express');
const db = require('../models');

const router = express.Router();

router.get('/', async (req, res, next) => {
  // GET /api/posts
  try {
    const posts = await db.Post.findAll({
      include: [
        {
          model: db.User,
          attributes: ['id', 'nickname'],
        },
        {
          model: db.Image,
        },
        {
          model: db.User,
          through: 'Like', // DB 테이블 명
          as: 'Likers', // 프론트에 전달할 객체의 key
          attributes: ['id'],
        },
      ],
      order: [
        ['createdAt', 'DESC'], // DESC는 내림차순, ASC는 오름차순(default)
      ],
    });

    return res.status(200).json(posts);
  } catch (e) {
    console.error(e);
    next(e);
  }
});

module.exports = router;

데이터가 프론트로 전달되는 형태

Redux devtools를 통해 state를 살펴보면 서버에서 데이터가 어떠한 형태로 프론트로 전달되었는지 확인할 수 있다.

models/post.jsdb.User.belongsToMany(db.Post, { through: 'Like', as: 'Liked' });에서 Post와 User의 M:N관계를 정의할 때 through와 as의 의미는 다음과 같다.

through는 포함시킬 DB의 table명 이고 -> Like
as는 프론트에 전달할 객체의 key이다. -> Likers

profile
JavaScript, Node.js 그리고 React를 배우는
post-custom-banner

0개의 댓글