좋아요 기능 넣기를 구현해볼 차례다.
우선 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 });
따라서 나는 다음과 같이 모델을 한 번에 모아 설정했다.
// 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];
그런데 여기서 문제가 발생한다.
모델 폴더의 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 끝...