Миграции
Предлагам ви да използвате миграции
вместо да правите 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());
});