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이다.
하단에서 게시글들을 가져올 때 데이터가 어떻게 프론트로 전달되는 지 알아보겠다.
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);
}
});
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.js
의 db.User.belongsToMany(db.Post, { through: 'Like', as: 'Liked' });
에서 Post와 User의 M:N관계를 정의할 때 through와 as의 의미는 다음과 같다.
through
는 포함시킬 DB의 table명 이고 -> Like
as
는 프론트에 전달할 객체의 key이다. -> Likers