Ответ 1
Миграция
Я предлагаю вам использовать sequelize migrations вместо sync()
для каждой модели. Существует модуль - sequelize.cli, который позволяет легко управлять миграциями и семенами. Это каким-то образом заставляет структуру проекта создавать файл инициализации index.js
внутри /models
каталога проекта. Он считает, что все ваши определения моделей будут в этом каталоге. Этот script выполняет итерацию по всем файлам модели (каждое определение модели находится в отдельном файле, например mentee.js
, question.js
), и выполняет sequelize.import()
, чтобы присвоить эти модели экземпляру sequelize - это позволяет вам получить к ним доступ позже через sequelize[modelName]
например sequelize.question
.
Примечание. при создании файлов миграции помните о полях временных меток - createdAt
, updatedAt
и, в конечном итоге, deletedAt
.
Синхронизировать
Лично я использую sync()
только при выполнении тестов - это может быть показано в три этапа
- выполнить
sequelize.sync({ force: true })
, чтобы синхронизировать все модели - запустите некоторую базу данных
seeds
(также можно выполнить черезsequelize-cli
), - выполнить тесты.
Это очень удобно, потому что вы можете очистить базу данных перед запуском тестов и, чтобы отличить разработку от тестов, тесты могут использовать разные базы данных, например. project_test
, так что база данных разработки остается неизменной.
Много-ко-многим
Теперь перейдем к вашей проблеме - отношение m: n между двумя моделями. Прежде всего, из-за того, что вы выполняете Promise.all()
, sync
может работать в другом порядке, чем вы добавляете в него функции. Чтобы избежать этой ситуации, я предлагаю вам использовать функцию mapSeries
обещания Bluebird
, которую Sequelize использует и предоставляет под sequelize.Promise
(это также является причиной вашей последней ошибки об удалении родительской строки - вы пытаетесь удалить mentees
, на который ссылается menteequestion
).
sequelize.Promise.mapSeries([
Mentee.sync({ force: true })
, Question.sync({ force: true })
, MenteeQuestion.sync({ force: true })
], (model) => { return model.destroy({ where: {} }); }).then(() => {
});
Первый параметр mapSeries
- это массив из promises, но второй - это функция, которая запускается с результатом каждого ранее определенного обещания. Из-за того, что Model.sync()
приводит к самой Модели, мы можем выполнить model.destroy()
на каждой итерации.
После этого вы можете вставить некоторые данные в базу данных через create()
, как в примере. Теперь время, чтобы исправить ошибку: mentee не связано с menteequestion! ошибка. Это происходит потому, что вы связали Mentee
с Question
, но между menteequestion
и Mentee
(или Question
) нет связи. Чтобы исправить это, после belongsToMany
вы можете добавить
MenteeQuestion.belongsTo(Mentee, { foreignKey: 'menteeId' });
MenteeQuestion.belongsTo(Question, { foreignKey: 'questionId' });
Теперь вы можете добавить include: [Mentee, Question]
при запросе menteequestion
. При выполнении toJSON()
вы также запускаете еще одну ошибку, потому что вы выполняете findAll
, который возвращает массив экземпляров. Вы можете сделать forEach()
menteeQuestions.forEach(menteeQuestion => {
console.log(menteeQuestion.toJSON());
});