Migraciones
Le sugiero que use secuencializar migraciones
en lugar de hacer sync()
en cada modelo. Hay un módulo - sequelize.cli
que te permite administrar migraciones y semillas fácilmente. De alguna manera, fuerza la estructura de un proyecto creando un archivo de inicialización index.js
dentro de /models
directorio del proyecto. Asume que todas las definiciones de su modelo estarán en este directorio. Este script itera a través de todos los archivos del modelo (cada definición de modelo está en un archivo separado, por ejemplo, mentee.js
, question.js
) y realiza sequelize.import()
para asignar esos modelos a la instancia de secuenciación; esto le permite acceder a ellos más tarde a través de sequelize[modelName]
p.ej. sequelize.question
.
createdAt
, updatedAt
y, finalmente, deletedAt
.
Sincronizar
Personalmente uso sync()
solo cuando ejecuto las pruebas; esto puede mostrarse en tres pasos
- realizar
sequelize.sync({ force: true })
para sincronizar todos los modelos - ejecutar algunas
seeds
de la base de datos (también se puede hacer a través desequelize-cli
), - realizar pruebas.
Esto es muy cómodo porque le permite limpiar la base de datos antes de ejecutar las pruebas y, para distinguir el desarrollo de las pruebas, las pruebas pueden usar una base de datos diferente, p. project_test
, para que la base de datos de desarrollo permanezca intacta.
Muchos a muchos
Ahora pasemos a su problema:la relación m:n entre dos modelos. En primer lugar, debido al hecho de que realiza Promise.all()
, la sync
puede ejecutarse en un orden diferente al que agrega las funciones en él. Para evitar esta situación, le sugiero que use mapSeries
característica de Bluebird
promesa, que Sequelize usa y expone bajo sequelize.Promise
(esta es también la razón de su último error sobre la eliminación de la fila principal:intenta eliminar mentees
al que se hace referencia desde menteequestion
).
sequelize.Promise.mapSeries([
Mentee.sync({ force: true })
, Question.sync({ force: true })
, MenteeQuestion.sync({ force: true })
], (model) => { return model.destroy({ where: {} }); }).then(() => {
});
Primer parámetro de mapSeries
es un arreglo de promesas, sin embargo la segunda es una función que se ejecuta con el resultado de cada promesa previamente definida. Debido al hecho de que Model.sync()
resultados en el modelo mismo, podemos ejecutar model.destroy()
en cada iteración.
Después de eso, puede insertar algunos datos en la base de datos a través de create()
, tal como en el ejemplo. Ahora es el momento de corregir el Error:¡el aprendiz no está asociado a la pregunta del aprendiz! error. Ocurre porque tienes Mentee
asociado con Question
pero no hay asociación entre MenteeQuestion
y Mentee
(o Question
). Para arreglar eso, después de belongsToMany
, puedes agregar
MenteeQuestion.belongsTo(Mentee, { foreignKey: 'menteeId' });
MenteeQuestion.belongsTo(Question, { foreignKey: 'questionId' });
Ahora puede agregar include: [Mentee, Question]
al consultar MenteeQuestion
. También se ejecutaría en otro error al hacer toJSON()
, porque haces findAll
que devuelve una matriz de instancias. Podrías hacer forEach()
menteeQuestions.forEach(menteeQuestion => {
console.log(menteeQuestion.toJSON());
});