TIL 좋아요 기능 넣기

ESH'S VELOG·2023년 7월 8일
0

좋아요 기능 넣기를 구현해볼 차례다.

우선 DB 관계설정부터 작성해보았다.

  • like는 게시글(post)에 넣게되고 게시글에 게시글은 여러개의 like를 가질 수 있다.

  • user는 한 게시글의 like를 한 번만 누를 수 있으며 user는 여러 게시글의 like를 가질 수 있다.

=> 즉 N:M 관계(다대다)

이 때 sequelize를 사용하여 모델을 설정할 때 belongsToMany를 사용하여 M:N관계를 설정해주면 된다.
define을 이용한 모델의 설정은 다음과 같다.
** sequelize 공식문서 발췌

UserProject = sequelize.define('user_project', {
  role: Sequelize.STRING
});
User.belongsToMany(Project, { through: UserProject });
Project.belongsToMany(User, { through: UserProject });
  • M:N 관계를 맺어주려는 테이블 서로 모두 설정을 해주고 중간 테이블(through)를 필수로 설정해야한다.

따라서 나는 다음과 같이 모델을 한 번에 모아 설정했다.

// import Models
const User = require('./users.js');
const Post = require('./posts.js');
const Comment = require('./comments.js');
const Like = require('./likes.js');

// User 관계 (1:M)
User.hasMany(Post);
User.hasMany(Comment);

// M:1
Post.belongsTo(User);
Comment.belongsTo(User);

// Post <-> Comment 관계 (1:M)
Post.hasMany(Comment);
Comment.belongsTo(Post);

// M:N 관계
User.belongsToMany(Post, { through: Like, foreignKey: 'userId' });
Post.belongsToMany(User, {
  through: Like,
  as: 'LikeUser',
  foreignKey: 'postId',
});

// Like안에 테이블을 다른 테이블들에 주기 위함
Like.hasMany(Post, { foreignKey: 'id' });
Like.hasMany(User, { foreignKey: 'id' });

module.exports = [User, Post, Comment, Like];
  • 여기서 중요한 포인트 한 가지!
    중간 테이블을 Like라고 설정하고 Like안의 테이블 내 정보들을 불러오기 위해 마지막 부분에 Like.hasMany를 사용하여 외래키인 id를 사용한다고 적었다.
    이렇게 설정해야 나중에 Like테이블의 db를 불러와서 활용할 수 있다.

그런데 여기서 문제가 발생한다.
모델 폴더의 likes.js로 설정한 테이블이 아무리 해도 생기지 않는것이다.
likes.js의 파일 내 내용은 다음과 같다.

const mysql = require('../dbMysql.js');

const Like = mysql.define('like',{},{timestamps:false});

module.exports=Like;

이유를 알 수 없어서 계속 시도해보다가 결국 index파일에서 각 모델들을 객체분해할당을 하여 sequelize의 기능인 sync()를 사용해서 강제로 테이블 생성을 시도하였다.

// import Models
const { User, Post, Comment, Like } = require('./index.js');

// User 관계 (1:M)
User.hasMany(Post);
User.hasMany(Comment);

// M:1
Post.belongsTo(User);
Comment.belongsTo(User);

// Post <-> Comment 관계 (1:M)
Post.hasMany(Comment);
Comment.belongsTo(Post);

// M:N 관계
User.belongsToMany(Post, { through: Like, foreignKey: 'userId' });
Post.belongsToMany(User, { through: Like, foreignKey: 'postId' });

// Like안에 테이블을 다른 테이블들에 주기 위함
Like.hasMany(Post, { foreignKey: 'id' });
Like.hasMany(User, { foreignKey: 'id' });

await User.sync();
await Post.sync();
await Comment.sync();
await Like.sync();

다시 DB를 생성한 결과 likes테이블은 생성었다.
DESC likes로 확인해보았다.
내 예상으로는 외래키인 userId, postId가 컬럼으로 존재할 줄 알았으나 PRIMARY KEY만 존재하였다.
이 말은 즉슨 내가 직접만든 likes파일이 적용이 되지 않았다는 얘기다.
그래서 이번에는 할 수 없이 다음과 같이 likes.js파일 내용을 바꾸었다.

const { DataTypes } = require('sequelize');
const mysql = require('../db.js');

const Like = mysql.define(
  'like',
  {
    // 기본 키(primary key) 제거
    userId: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
    postId: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
  },
  {
    timestamps: false,
    primaryKey: false, // 기본 키(primary key) 생성 비활성화
  }
);

module.exports = Like;

위와 같이 수정 후
DESC likes 결과

postId와 userId는 생성되었으나 아직도 primaryId는 존재한다...
과연 postId와 userId는 다른 테이블과 잘 연결이 되었을지도 의문이다.

DBeaver로 조회한 결과 아무런 관계도가 생성되지 않았다.

혹시 몰라서 원래 다른사람에게 배운 repo를 보고 딱 한줄로 해결이 되었다.

그 한 줄은 뭐였냐면 app.js파일에 model을 불러오는 한 줄이었다.

// models
const models = require('./Database/Models/index.js');

나는 라이브러리가 아닌 다른 것은 호출이 필요없다고 생각했었는데 모델 폴더도 호출이 필요했었나보다 ....
다시 app.js파일을 보니 router나 DB를 생성하는 것 모두 호출이 되어있었다. models폴더는 app.js에서 재 호출이 되진 않았지만 모델 폴더가 있음으로 인해 모델에 내가 설정해놓은 값으로 테이블이 생성된다는 것을 깨달았다...
너무 허무하고 이걸 생성시키려고 몇 시간을 보낸걸 보면 ....바보같다는 생각도 들고...하

DBeaver로 봤을때도 엔티티의 관계도가 제대로 생성된 것을 확인할 수 있었다...
오늘의 TIL 끝...

profile
Backend Developer - Typescript, Javascript 를 공부합니다.

0개의 댓글