Миграции
Предлагам ви да използвате миграции
вместо да правите sync() на всеки модел. Има модул - sequelize.cli
което ви позволява лесно да управлявате миграциите и семена. Той по някакъв начин налага структура на проекта чрез създаване на файл за инициализация index.js вътре в /models директория на проекта. Предполага се, че всички ваши модели дефиниции ще бъдат в тази директория. Този скрипт преглежда всички файлове на модела (всяка дефиниция на модела е в отделен файл, напр. 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 е масив от обещания, но вторият е функция, която се изпълнява с резултата от всяко предварително дефинирано обещание. Поради факта, че Model.sync() резултати в самия модел, можем да изпълним model.destroy() при всяка итерация.
След това можете да вмъкнете някои данни в базата данни чрез create() , точно както в примера. Сега е време да поправите Грешката:наставляваният не е свързан с въпрос на менте! грешка. Това се случва, защото сте свързали 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());
});