인프런 커뮤니티 질문&답변

Backend Woonie님의 프로필 이미지
Backend Woonie

작성한 질문수

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지

9장 데이테베이스 세팅하기 TypeError: model.initiate is not a function

해결된 질문

작성

·

42

0

질문이 좀 많습니다. 질문에 비슷한 사례가 있는데 도저히 해결이 안 되어서 다시 여쭤봅니다.

에러 메시지는 다음과 같습니다.

C:\developing\zeroCho\nodeJs\nodebird\models>node index.js
hashtag.js Hashtag
old-index.js undefined
C:\developing\zeroCho\nodeJs\nodebird\models\index.js:30
    model.initiate(sequelize);
          ^

TypeError: model.initiate is not a function


코드 본문입니다.

const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];

const db = {};
const sequelize = new Sequelize(
  config.database, config.username, config.password, config,
);

db.sequelize = sequelize;

const basename = path.basename(__filename);
fs
  .readdirSync(__dirname) // 현재 폴더의 모든 파일을 조회
  .filter(file => { // 숨김 파일, index.js, js 확장자가 아닌 파일 필터링
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => { // 해당 파일의 모델 불러와서 init
    const model = require(path.join(__dirname, file));
    console.log(file, model.name);
    db[model.name] = model;
    model.initiate(sequelize); // 문제 발생점
  });

Object.keys(db).forEach(modelName => { // associate 호출
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

module.exports = db;


콘솔 한번 찍어보고 싶은데 해당 오류 때문에 진도를 못 나가고 있네요. 도대체 뭐가 문제인지 모르겠습니다.

 

답변 2

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

old-index.js를 왜 넣으신건가요? 지우셔야 합니다. 모델 파일 외에는 있으면 안 됩니다.

네네 해당 파일 삭제하였고 다른 모델 파일에서

(예를 들면 hashtag.js에서)

const Sequelize = require("sequelize");

class Hashtag extends Sequelize.Model {
  static init(sequelize) {
    super.init(
      {
        title: {
          type: Sequelize.STRING(15),
          allowNull: false,
          unique: true,
        },
      },
      {
        sequelize,
        timestamps: true,
        underscored: false,
        modelName: "Hashtag",
        tableName: "hashtags",
        paranoid: false,
        charset: "utf8mb4",
        collate: "utf8mb4_general_ci",
      }
    );
  }

  static associate(db) {
    db.Hashtag.belongsToMany(db.Post, { through: "PostHashtag" });
  }
}

module.exports = Hashtag;

이런 식으로 통일시키고, index.js에서도 일단 model.init(sequelize)로 수정해서 에러를 처리하긴 했는데 이게 옳게 된건지 잘 모르겠습니다..

.forEach((file) => {
    const model = require(path.join(__dirname, file));
    console.log(model);
    db[model.name] = model;
    model.init(sequelize);
  }); 

이렇게 해서 찍어보면

C:\developing\zeroCho\nodeJs\nodebird\models>node index.js
Hashtag
Post
User

이렇게 잘 나오고 있긴 합니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

네 잘 된 것 같은데요. 정확히는 워크벤치 열어서 테이블 확인하긴 해야합니다.

0

안녕하세요, 인프런 AI 인턴입니다. Backend Woonie님.

현재 발생하고 있는 에러인 TypeError: model.initiate is not a function은 주로 모델 파일의 initiate 메서드에 대한 문제로 보입니다. 에러 메시지와 함께 제공된 코드에 따르면, 각 모델 파일에서 initiate라는 메서드를 호출하려 하고 있지만, 실제로는 그런 메서드가 정의되지 않았을 가능성이 큽니다.

보통 Sequelize를 사용할 때, 모델 클래스는 init 메서드를 사용하여 초기화됩니다. 따라서 각 모델 파일을 확인하여 initiate 대신 init을 사용하고 있는지 확인해 보세요.

아래 링크들은 유사한 문제를 해결한 사례들을 포함하고 있으니 참고하시면 좋습니다:

  1. “백엔드 서버에서 index.js 에러” - 모델 파일에서 module.exports가 올바르게 설정되어 있는지 확인하는 방법을 설명합니다.

  2. “노드버드 7장 오류 질문드립니다” - Sequelize 모델 설정 및 데이터베이스 연결 문제를 다루고 있습니다.

간단히 요약하면, 각 모델 파일에서 클래스가 Sequelize.Model을 상속받고, static init 메서드 내부에서 모델을 설정하고 있는지 확인해야 합니다. 예를 들어, initiate가 아니라 init이라고 사용되어야 합니다:

class ModelName extends Sequelize.Model {
  static init(sequelize) {
    super.init({
      /* column definitions */
    }, {
      sequelize,
      modelName: 'ModelName',
      /* additional options */
    });
  }
}

또한, 각 모델 파일이 제대로 module.exports에 설정되어 있는지 확인해 주시기 바랍니다. 즉, 파일 끝부분에 module.exports = ModelName;와 같이 정의되어 있어야 합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

Backend Woonie님의 프로필 이미지
Backend Woonie

작성한 질문수

질문하기