Tony
Tony

Reputation: 19151

Sequelize associations don't return with `{include: all}` when using multiple `belongsTo` on same model

I have an Appointment model that has both a student and a teacher. So teachers have many appointments, students have many appointments, and appointments belong to one teacher and one student through distinct foreign keys referencing the same model.

  Appointment.associate = function (models) {
    Appointment.Teacher = Appointment.belongsTo(models.Account, {
      as: 'teacher',
      foreignKey: 'teacherId'
    });
  };

  Appointment.associate = function (models) {
    Appointment.Student = Appointment.belongsTo(models.Account, {
      as: 'student',
      foreignKey: 'studentId'
    });
  };

If I query and include all associations, neither the student nor the teacher is included:

  const appointment = await db.Appointment.findOne({
    where: { id: req.params.id },
    include: { all: true }
  });

If I query and specify the associations specifically, I get an error:

const appointment = await db.Appointment.findOne({
    where: { id: req.params.id },
    include: [{ model: db.Account, as: 'student' }, { model: db.Account, as: 'teacher' }]
  });
// Gives me SequelizeEagerLoadingError: account is not associated to appointments!

Is this a bug or am I doing something wrong? I've seen a few other posts about this but still can't resolve. I'm using sequelize 5.8.0 with mysql.

Upvotes: 0

Views: 2053

Answers (2)

KenOn10
KenOn10

Reputation: 1968

Try combining both belongsTo() calls into a single Appointment.associate method, as @GregBelyea has done. As written, I think the 1st one is overwriting the 2nd (this you could test by including only student).

I tried the simple hack-test below and it worked fine, showing meetings with both teacher and student.

    Meeting.belongsTo(User, {as: 'teacher', foreignKey: 'teacher_id'});
    Meeting.belongsTo(User, {as: 'student', foreignKey: 'student_id'});       
    Meeting.findAll({include: { all: true }})

Upvotes: 1

Greg Belyea
Greg Belyea

Reputation: 878

Well... i think you should probably set it up as a hasOne rather than a belongsTo if you want to query it that way..... It appears to me that the Appointment is the parent and the Teacher and Student are the child relations. You are saying, give me all the accounts associated with this appointment.... But then saying that an appointment is an attribute of Account, not the other way around... Try switching that up, maybe something more like this... something looked funny up there in that association code

Appointment.associate = function (models) {
    Appointment.hasOne(models.Teacher , {
      as: 'teacher', foreignKey: 'teacher_id',
    });
    Appointment.hasOne(models.Student, {
      as: 'sturdent', foreignKey: 'student_id',
    });
  }

I'd need to see your actual models to know for sure, but i think this would be closer, you may have to use sourceKey as well, but i can't tell from the snippet

Upvotes: 1

Related Questions