简体   繁体   中英

Express and sequelize: eager loading belongs to many associations hangs application

I'm attempting to eager load a belongs-to-many association where I am loading three nested associations. Here are the models, which result in three database tables programs , programDates and peopleProgramDates

program.js :

module.exports = function(sequelize, DataTypes) {
  const Program = sequelize.define('program', {
    name: DataTypes.STRING
  });

  Program.associate = ({programDate}) => {
    Program.hasMany(programDate);
  };

  return Program;
};

program_date.js :

module.exports = function(sequelize, DataTypes) {
  const ProgramDate = sequelize.define('programDate', {
    date: DataTypes.DATEONLY,
    volunteerLimit: DataTypes.INTEGER
  }, {
    indexes: [
      {
        unique: true,
        fields: ['programId', 'date']
      }
    ]
  });

  ProgramDate.associate = ({program, person}) => {
    ProgramDate.belongsTo(program);
    ProgramDate.belongsToMany(person, {through: 'peopleProgramDates'});
  };

  return ProgramDate;
};

In my controller, I want to return an object with all of the programs, programDates and peopleProgramDates:

const {bus, family, person, volunteerType, program, programDate} = require('../models');

exports.get = (request, response) => {
  return Promise.all([
    bus.findAll({ include: [{model: family, include: [person]}] })
        .then(buses => buses.map(addBusCount)),
    volunteerType.findAll({include: [person]})
        .then(volunteerTypes => volunteerTypes.map(addVolunteerCount)),

    // this query hangs the application
    program.findAll( { include: [{ model: programDate, include: [{association: 'peopleProgramDates'}] }]} )
        .then(programs => programs.map(processPrograms))

  ])
      .then(([buses, volunteerTypes, programs]) =>
        response.render('pages/register', {
          buses,
          volunteerTypes,
          programs
        })
      );
};

At the moment, processPrograms() is a function that simply returns the same array of objects, and so should not be relevant here. addBusCount and addVolunteerCount should similarly not be relevant.

I think the issue may be that peopleProgram dates is not a real sequelize model, but the result of the the belongsToMany through: association on ProgramDate .

This post seems to suggest I can use the association: property in order to load the data from the through association, however the query hangs the application.

If I remove the join table from the query, then the data loads fine:

program.findAll( { include: [programDate] } )

Bonus points: Ultimately what I really need is simply a count of peopleProgramDates returned with the programDate objects. Perhaps I can simply define such on the programDates model, however perhaps we can address that in a separate question. Nevertheless, if there is a compelling reason to use this approach, such as performance, then maybe we should go that way after all.

The solution was to add an alias to the belongsToMany through association:

// program_date.js
ProgramDate.belongsToMany(person, {through: 'peopleProgramDates', as: 'peopleProgDates'});

And then reference the alias in the include property:

program.findAll( { include: [{ model: programDate, include: [{association: 'peopleProgDates'}] }]} )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM