Sequelize N:M associate
JOIN 기능을 구현하기 위해 시퀄라이즈 모델 간의 관계를 설정하기 위한 메서드이다.
N:M
게시글 모델과 게시글에 속해있는 해시태그 모델 간의 다대다 관계
- 게시글 하나의 여러 개의 해시태그가 속할 수 있다.
- 해시태그 하나가 여러 개의 게시글의 속할 수 있다.
- belongsToMany 메서드로 표현한다.
- 다대다 관계 특성상 중간 테이블이 생성된다.
const Sequelize = require("sequelize");
module.exports = class Post extends Sequelize.Model {
static init(sequelize) {
return super.init({
title: {
type: Sequelize.STRING(50),
allowNull: false,
},
content: {
type: Sequelize.STRING(100),
allowNull: false,
},
}, {
sequelize,
timestamps: true,
paranoid: true,
underscored: false,
modelName: "Post",
tableName: "posts",
charset: "utf8",
collate: "utf8_general_ci",
})
}
static associate(db) {
db.Post.belongsToMany(db.Hashtag, { through: "PostHashtag", });
}
}
models > post.js
- 하나의 게시글은 여러 개의 해시태그를 포함할 수 있으므로 belongsToMany 메서드를 사용한다.
- through 속성에 중간 테이블 이름을 정의한다.
const Sequelize = require("sequelize");
module.exports = class Hashtag extends Sequelize.Model {
static init(sequelize) {
return super.init({
tag: {
type: Sequelize.STRING(20),
allowNull: false,
}
}, {
sequelize,
timestamps: true,
paranoid: true,
underscored: false,
modelName: "Hashtag",
tableName: "hashtags",
charset: "utf8",
collate: "utf8_general_ci",
})
}
static associate(db) {
db.Hashtag.belongsToMany(db.Post, { through: "PostHashtag" });
}
}
models > hashtag.js
- 하나의 해시태그는 여러 개의 게시글에 속할 수 있으므로 belongsToMany 메서드를 사용한다.
- through 속성에 중간 테이블 이름을 정의한다.
const Sequelize = require("sequelize");
const Post = require("./post");
const Hashtag = require("./hashtag");
const env = process.env.NODE_ENV || "development";
const config = require("../config/config.json")[env];
const db = {};
const sequelize = new Sequelize(
config.database, config.username, config.password, config
);
db.sequelize = sequelize;
db.Post = Post;
db.Hashtag = Hashtag;
Post.init(sequelize);
Hashtag.init(sequelize);
Post.associate(db);
Hashtag.associate(db);
module.exports = db;
models > index.js
- 게시글 모델과 해시태그 모델을 불러온다.
- 불러온 모델들을 db 객체에 담고 init 메서드를 사용하여 호출한다.
- associate 메서드에 db 객체를 넣어 호출한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
div {
margin-bottom: 20px;
}
input {
width: 140px;
}
</style>
</head>
<body>
<div>
<form action="/" method="post">
<div>
<input type="text" name="title" placeholder="title">
</div>
<div>
<input type="text" name="test" placeholder="hashtag">
</div>
<div>
<textarea name="content" placeholder="content"></textarea>
</div>
<button>작성</button>
</form>
</div>
</body>
</html>
views / index.html
- 폼 태그로 데이터를 보낸다.
- 서버에서 데이터는 req.body로 확인할 수 있다.
const router = require("express").Router();
const postController = require("../controllers/postController");
router.get("/", postController.getPosts);
router.post("/", postController.writePost);
module.exports = router;
routes > post.js
const models = require("../models");
exports.getPosts = async (req, res) => {
const title = await models.Hashtag.findOne({
where: { tag: "노드" },
});
const result = await title.getPosts();
res.status(200).json(result);
};
exports.writePost = async (req, res) => {
const { title, content, test } = req.body;
const post = await models.Post.create({
title,
content,
});
const result = await models.Hashtag.findOrCreate({
where: { tag: test },
});
await post.addHashtag(result[0]);
res.status(201).json({
message: "success",
});
};
controllers > postController.js
- "/" 경로로 get 요청을 통해 해시태그가 속한 게시글들을 확인한다.
- "/" 경로로 post 요청을 통해 게시글과 해시태그를 작성한다.
- 해시태그를 먼저 찾은 후 get 관계 메서드를 사용하여 해시태그에 속해있는 게시글들을 가져온다.
- 게시글/해시태그 작성 후 해시태그 결과를 add 관계 메서드를 사용해 PostHashtag 모델에 넣어준다.
- 단수/복수 사용의 주의해야 한다. 하나의 게시글은 getPost 여러 개의 게시글은 getPosts
'데이터베이스' 카테고리의 다른 글
MySQL 자료형 옵션 (0) | 2022.05.08 |
---|---|
DBMS RDBMS Transaction (0) | 2022.05.08 |
Sequelize 1:N associate (0) | 2022.05.05 |
Sequelize 1:1 associate (0) | 2022.05.05 |
Sequelize Model (0) | 2022.05.04 |