Sequelize - M:N 관계, DB config 암호화

BigbrotherShin·2020년 3월 17일
0

Backend

목록 보기
2/15
post-thumbnail

M:N 관계

참조 : 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'
});

적용

model/user.js

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;
};

M:N 관계 또는 belongsTo 일 때 as를 써야하는 이유

서버에 데이터를 요청할 때, as 이름으로 가져오기 때문이다.

// 데이터 가져올 때, as 이름으로 가져온다.
const user = {
  id: 1,
  nickname: 'SJH',
  Liked: [{post1}, {post2}, {post3}, ...],
  Posts: [{post1}, {post2}],
  Followers: [{user1}, {user2}, {user3}]
};

route에서 User 데이터 불러오기

routes/user.js

...

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);
});

config.json 파일 암호화

sequelize config 파일에는 MySql 암호같은 민감정보가 들어있으므로, 민감정보를 dotenv라이브러리를 통해 .env파일에 따로 저장해야 한다.

먼저 config폴더 안의 config.json파일의 이름을 config.js로 바꾸어준다. 이는 JavaScript 모듈을 활용하여 dotenv라이브러리를 활용하기 위함이다.

backend/config/config.js

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,
  },
};

backend/.env

DB_PASSWORD: 비밀번호

References

profile
JavaScript, Node.js 그리고 React를 배우는

0개의 댓글