Skip to content

모델, 마이그레이션 파일 생성하기

박지율 edited this page Jun 21, 2021 · 4 revisions

모델

기사 모델을 생성하여 기자와 함께 살펴보기

sequelize 공식 사이트

sequelize-cli로 마이그레이션 파일을 생성하면 데이터베이스의 스키마를 변경했을 때 쉽게 이를 데이터베이스에 적용할 수 있다. 참조

그래서 아래와 같은 명령어로 간단하게 Article, Author이라는 마이그레이션 파일을 만들 수 있다.

npx sequelize-cli model:generate --name Article --attributes headline:string,author:string

npx sequelize-cli model:generate --name Author --attributes email:string,name:string,password:string

명령어를 실행하면 /models, /migrations 디렉토리에 생성한 파일이 생긴다.

생성된 testArticle, testAuthor에 현재 깃 저장소에 있는 모델과 마이그레이션 파일을 복사 붙여넣기 하면 아래와 같은 코드가 된다.

마이그레이션
# migrations/20210601013656-create-article.js

'use strict';
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('Articles', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      headline: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      category: {
        type: Sequelize.INTEGER,
        allowNull: false,
      },
      author: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      image: {
        type: Sequelize.STRING,
      },
      imageDesc: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      imageFrom: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      briefing: {
        type: Sequelize.TEXT,
        allowNull: false,
      },
      am7: {
        type: Sequelize.BOOLEAN,
        defaultValue: false,
        allowNull: false,
      },
      pm7: {
        type: Sequelize.BOOLEAN,
        defaultValue: false,
        allowNull: false,
      },
      status: {
        type: Sequelize.INTEGER,
        defaultValue: 1,
        allowNull: false,
      },
      AuthorId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        onDelete: 'cascade',
        references: {
          model: 'Authors',
          key: 'id',
        },
      },
      publishedAt: {
        allowNull: true,
        type: Sequelize.DATE,
      },
      paragraphs: {
        type: Sequelize.JSON,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('Articles');
  },
};

# migrations/20210601013656-create-author.js

'use strict';
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('Authors', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      email: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      code: {
        type: Sequelize.INTEGER,
        allowNull: false,
      },
      position: {
        type: Sequelize.INTEGER,
        defaultValue: 1,
        allowNull: false,
      },
      contact: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      password: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      photo: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('Authors');
  },
};
모델
# models/Article.js

const { Model } = require('sequelize');
const converter = require('../lib/converter');
const moment = require('moment');

module.exports = (sequelize, DataTypes) => {
  class Article extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate({ Author }) {
      this.belongsTo(Author);
      // define association here
    }
  }
  Article.init(
    {
      headline: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          len: [1, 30],
        },
      },
      category: {
        type: DataTypes.INTEGER,
        allowNull: false,
        get() {
          return converter.category(this.getDataValue('category'));
        },
      },
      author: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      image: {
        type: DataTypes.STRING,
      },
      imageDesc: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      imageFrom: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      briefing: {
        type: DataTypes.TEXT,
        allowNull: false,
      },
      am7: {
        type: DataTypes.BOOLEAN,
        defaultValue: false,
        allowNull: false,
      },
      pm7: {
        type: DataTypes.BOOLEAN,
        defaultValue: false,
        allowNull: false,
      },
      status: {
        type: DataTypes.INTEGER,
        defaultValue: 1,
        allowNull: false,
      },
      publishedAt: {
        allowNull: true,
        type: DataTypes.DATE,
        get() {
          return moment(this.getDataValue('publishedAt')).format('YYYY.MM.DD HH:mm:ss');
        },
      },
      paragraphs: {
        type: DataTypes.JSON,
      },
      createdAt: {
        allowNull: false,
        type: DataTypes.DATE,
        get() {
          return moment(this.getDataValue('createdAt')).format('YYYY.MM.DD HH:mm:ss');
        },
      },
      updatedAt: {
        allowNull: false,
        type: DataTypes.DATE,
        get() {
          return moment(this.getDataValue('updatedAt')).format('YYYY.MM.DD HH:mm:ss');
        },
      },
    },
    {
      sequelize,
      modelName: 'Article',
    },
  );
  return Article;
};


# models/Aurhor.js

'use strict';
require('dotenv').config();
const { Model } = require('sequelize');
const authorValidator = require('./validator/authorValidator');
const bcrypt = require('bcrypt');

module.exports = (sequelize, DataTypes) => {
  class Author extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate({ Article }) {
      this.hasMany(Article);
    }

    validPassword(password) {
      return bcrypt.compare(password, this.password).then((result) => result);
    }
  }

  Author.init(
    {
      email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: {
          msg: '이미 존재하는 이메일입니다.',
        },
      },
      name: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      code: {
        type: DataTypes.INTEGER,
        allowNull: false,
        validate: {
          customValidator(value) {
            authorValidator.code(value);
          },
        },
      },
      position: {
        type: DataTypes.INTEGER,
        defaultValue: 1,
        allowNull: false,
      },
      contact: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          customValidator(value) {
            authorValidator.contact(value);
          },
        },
      },
      password: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          customValidator(value) {
            authorValidator.password(value);
          },
        },
      },
      photo: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          notNull: {
            msg: '사진을 첨부해 주세요',
          },
        },
      },
    },
    {
      sequelize,
      modelName: 'Author',
    },
  );
  return Author;
};

기자가 결국 여러개의 기사를 작성할 수 있으므로 기사라는 모델은 기자와 관련성이 있습니다.

따라서 직접 코드와 같이 Author, Article model에서 static associate부분에서 두 모델의 관계를 정의할 수 있습니다.

Clone this wiki locally