sql >> Base de Datos >  >> RDS >> Mysql

Ejemplo simple de relación de muchos a muchos usando Sequelize

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 .

Nota: al crear archivos de migración, recuerde los campos de marcas de tiempo - createdAt , updatedAt y, finalmente, deletedAt .

Sincronizar

Personalmente uso sync() solo cuando ejecuto las pruebas; esto puede mostrarse en tres pasos

  1. realizar sequelize.sync({ force: true }) para sincronizar todos los modelos
  2. ejecutar algunas seeds de la base de datos (también se puede hacer a través de sequelize-cli ),
  3. 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());
});