Mysql
 sql >> Database >  >> RDS >> Mysql

Semplice esempio di relazione molti-a-molti usando Sequelize

Migrazioni

Ti suggerirei di utilizzare sequelize migrations invece fare sync() su ogni modello. C'è un modulo - sequelize.cli che ti permette di gestire facilmente migrazioni e seed. In qualche modo, forza una struttura di progetto creando il file di inizializzazione index.js all'interno di /models directory del progetto. Si presume che tutte le definizioni del modello siano in questa directory. Questo script scorre tutti i file del modello (ogni definizione del modello è in un file separato, ad es. mentee.js , question.js ) ed esegue sequelize.import() per assegnare quei modelli all'istanza di sequelize - questo ti consente di accedervi in ​​seguito tramite sequelize[modelName] per esempio. sequelize.question .

Nota: quando crei i file di migrazione, ricorda i campi timestamp - createdAt , updatedAt e, eventualmente, deletedAt .

Sincronizza

Personalmente uso sync() solo quando eseguo i test - questo può essere mostrato in tre passaggi

  1. esegui sequelize.sync({ force: true }) per sincronizzare tutti i modelli
  2. esegui alcuni seeds del database (può anche essere fatto tramite sequelize-cli ),
  3. esegui test.

Questo è molto comodo perché consente di pulire il database prima di eseguire i test e, per distinguere lo sviluppo dai test, i test possono utilizzare database diversi, ad es. project_test , in modo che il database di sviluppo rimanga intatto.

Molti a molti

Passiamo ora al tuo problema:m:n relazione tra due modelli. Prima di tutto, perché esegui Promise.all() , la sync può essere eseguito in un ordine diverso rispetto a quello in cui aggiungi le funzioni al suo interno. Per evitare questa situazione ti consiglio di usare mapSeries caratteristica di Bluebird promise, che Sequelize utilizza ed espone in sequelize.Promise (questo è anche il motivo del tuo ultimo errore sull'eliminazione della riga principale:provi a eliminare i mentees a cui si fa riferimento da menteequestion ).

sequelize.Promise.mapSeries([
    Mentee.sync({ force: true })
  , Question.sync({ force: true })
  , MenteeQuestion.sync({ force: true })
], (model) => { return model.destroy({ where: {} }); }).then(() => {

});

Primo parametro di mapSeries è un array di promesse, tuttavia la seconda è una funzione che viene eseguita con il risultato di ciascuna promessa precedentemente definita. A causa del fatto che Model.sync() risulta nel modello stesso, possiamo eseguire model.destroy() ad ogni iterazione.

Dopodiché puoi inserire alcuni dati nel database tramite create() , proprio come nell'esempio. Ora è il momento di correggere l'Errore:mentee non è associato a menteequestion! errore. Si verifica perché hai associato Mentee con Question ma non c'è alcuna associazione tra MenteeQuestion e Mentee (o Question ). Per risolvere il problema, dopo belongsToMany , puoi aggiungere

MenteeQuestion.belongsTo(Mentee, { foreignKey: 'menteeId' });
MenteeQuestion.belongsTo(Question, { foreignKey: 'questionId' });

Ora puoi aggiungere include: [Mentee, Question] quando si interroga MenteeQuestion . Dovresti anche eseguire un altro errore durante l'esecuzione di toJSON() , perché fai findAll che restituisce una matrice di istanze. Potresti fare forEach()

menteeQuestions.forEach(menteeQuestion => {
    console.log(menteeQuestion.toJSON());
});