데이터베이스

Sequelize N:M associate

realtrynna 2022. 5. 5. 22:56

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

 

 

Post 모델
Hashtag 모델
PostHashtag 모델

'데이터베이스' 카테고리의 다른 글

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