참조 : node.js - How to implement many to many association in sequelize - Stack Overflow
Parent.belongsToMany( Child, {
as: [Relationship],
through: [Parent_Child] //this can be string or a model,
foreignKey: 'Parent_rowId'
});
Child.belongsToMany(Parent, {
as: [Relationship2],
through: [Parent_Child],
foreignKey: 'Child_rowId'
});
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
'User', // 테이블명은 users 로 자동으로 바뀜
{
nickname: {
type: DataTypes.STRING(20), // 20 글자 이하
allowNull: false, // 필수
},
userId: {
type: DataTypes.STRING(20),
allowNull: false,
unique: true, // 고유한 값
},
password: {
type: DataTypes.STRING(100), // 100 글자 이하
allowNull: false,
},
},
{
charset: 'utf8',
collate: 'utf8_general_ci', // 설정해줘야 한글이 저장됨
},
);
User.associate = db => {
db.User.hasMany(db.Post, { as: 'Posts' }); // as 를 통해 조합이 같은 테이블과 구별. 꼭 적어줘야함.
//db.User.belongsToMany(db.Post, { through: 'Like' });과 구별
db.User.hasMany(db.Comment);
db.User.belongsToMany(db.Post, { through: 'Like', as: 'Liked' }); // belongsToMany 관계는 as를 달아주는 게 좋다.
db.User.belongsToMany(db.User, {
through: 'Follow',
as: 'Followers', // 같은 테이블 끼리 다대다관계이면 구별을 위해 as로 구별. JavaScript 객체에서 사용할 이름
foreignKey: 'followingId', // DB 컬럼명: 반대로 쓰는 이유는 foreignKey가 남의 테이블 id를 가리키기 때문
});
db.User.belongsToMany(db.User, {
through: 'Follow',
as: 'Follwings',
foreignKey: 'followerId', // DB 컬럼명: 반대로 쓰는 이유는 foreignKey가 남의 테이블 id를 가리키기 때문
});
};
return User;
};
서버에 데이터를 요청할 때, as 이름으로 가져오기 때문이다.
// 데이터 가져올 때, as 이름으로 가져온다.
const user = {
id: 1,
nickname: 'SJH',
Liked: [{post1}, {post2}, {post3}, ...],
Posts: [{post1}, {post2}],
Followers: [{user1}, {user2}, {user3}]
};
...
router.post('/login', (req, res, next) => {
// POST /api/user/login
passport.authenticate('local', (err, user, info) => {
// (err, user, info) 는 passport의 done(err, data, logicErr) 세 가지 인자
if (err) {
// 서버에 에러가 있는 경우
console.error(err);
next(err);
}
if (info) {
// 로직 상 에러가 있는 경우
return res.status(401).send(info.reason);
}
return req.login(user, async loginErr => {
try {
if (loginErr) {
return next(loginErr);
}
const fullUser = await db.User.findOne({
where: { id: user.id },
include: [
{
model: db.Post,
as: 'Posts',
attributes: ['id'],
},
{
model: db.User,
as: 'Followers',
attributes: ['id'],
},
{
model: db.User,
as: 'Followings',
attributes: ['id'],
},
],
attributes: ['id', 'nickname', 'userId'],
});
return res.status(200).json(fullUser); // 프론트에서 result.data로 조회 가능
} catch (e) {
next(e);
}
});
})(req, res, next);
});
sequelize config 파일에는 MySql 암호같은 민감정보가 들어있으므로, 민감정보를 dotenv
라이브러리를 통해 .env
파일에 따로 저장해야 한다.
먼저 config폴더 안의 config.json
파일의 이름을 config.js
로 바꾸어준다. 이는 JavaScript 모듈을 활용하여 dotenv
라이브러리를 활용하기 위함이다.
const dotenv = require('dotenv');
dotenv.config();
module.exports = {
development: {
username: 'root',
password: process.env.DB_PASSWORD,
database: 'react-nodebird',
host: '127.0.0.1',
dialect: 'mysql',
operatorsAliases: false,
},
test: {
username: 'root',
password: process.env.DB_PASSWORD,
database: 'react-nodebird',
host: '127.0.0.1',
dialect: 'mysql',
operatorsAliases: false,
},
production: {
username: 'root',
password: process.env.DB_PASSWORD,
database: 'react-nodebird',
host: '127.0.0.1',
dialect: 'mysql',
operatorsAliases: false,
},
};
DB_PASSWORD: 비밀번호