question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Include on through association

See original GitHub issue

What are you doing?

I have two models, Patient, and Device that are linked through a reference table PatientDevice. The linking table also contains references to the User table about who made changes to the associations (createdBy, updatedBy, etc). When I use an include within the through block of a query, it results in a Cannot read property 'indexOf' of undefined error

'use strict';

const Sequelize = require('sequelize');

const sequelize = new Sequelize('test', 'postgres', 'postgres', {
    dialect: 'postgres'
});

(async function() {
    await sequelize.authenticate();

    const User = sequelize.define('user', {
        name: Sequelize.STRING
    });

    const Patient = sequelize.define('patient', {
        name: Sequelize.STRING
    });

    const Device = sequelize.define('device', {
        serial: Sequelize.STRING
    });

    const PatientDevice = sequelize.define('patientDeviceAssociation', {
        patient: {
            type: Sequelize.INTEGER,
            foreignKey: {
                references: Patient
            }
        },
        device: {
            type: Sequelize.INTEGER,
            foreignKey: {
                references: Device
            }
        },
        createdBy: {
            type: Sequelize.INTEGER,
            foreignKey: {
                references: User
            }
        },
        updatedBy: {
            type: Sequelize.INTEGER,
            foreignKey: {
                references: User
            }
        }
    });

    Device.belongsToMany(Patient, {
        through: PatientDevice,
        foreignKey: 'device',
        otherKey: 'patient'
    });

    PatientDevice.belongsTo(User, {
        as: 'creator',
        foreignKey: 'createdBy'
    });

    PatientDevice.belongsTo(User, {
        as: 'updater',
        foreignKey: 'updatedBy'
    });

    await sequelize.sync({force: true});

    const user = await User.create({name: 'Dr. Jimmie'});
    const device = await Device.create({serial: '1234'});
    const patient = await Patient.create({name: 'Sick Doris'});
    await device.addPatient(patient, {through: {createdBy: user.id, updatedBy: user.id}});

    // This does not return the creator or updater users
    const foundDevice = await Device.findOne({
        where: { serial: '1234' },
        include: [
            { all: true, nested: true }
        ]
    });
    console.dir(foundDevice.toJSON(), {depth: null});

    // this does return the association
    const foundAssociation = await PatientDevice.findOne({include: [ {all: true, any: true}]});
    console.dir(foundAssociation.toJSON(), {depth: null});

    // This causes the crash and exception below
    const foundDevice2 = await Device.findOne({
        where: { serial: '1234' },
        include: [
            {
                model: Patient,
                through: {
                    // commenting out the include property stops the crash
                    include: [
                        {
                            model: User,
                            as: 'creator'
                        },
                        {
                            model: User,
                            as: 'updater'
                        }
                    ]
                }
            }
        ]
    });
    console.dir(foundDevice2.toJSON(), {depth: null});
    await sequelize.close();
})();

What do you expect to happen?

(if it works) A response containing the creator and updater associations, or (if it doesn’t work) no exception to be thrown and the include in the through to be ignored

// const device = ...
{
    id: 1,
    serial: '1234',
    createdAt: '2019 - 04 - 23T11: 42: 53.364Z',
    updatedAt: '2019 - 04 - 23T11: 42: 53.364Z',
    patients:
        [{
            id: 1,
            name: 'Sick Doris',
            createdAt: '2019 - 04 - 23T11: 42: 53.369Z',
            updatedAt: '2019 - 04 - 23T11: 42: 53.369Z',
            patientDeviceAssociation:
            {
                patient: 1,
                device: 1,
                createdBy: 1,
                updatedBy: 1,
                createdAt: '2019 - 04 - 23T11: 42: 53.382Z',
                updatedAt: '2019 - 04 - 23T11: 42: 53.382Z',
                creator:
                {
                    id: 1,
                    name: 'Dr. Jimmie',
                    createdAt: '2019 - 04 - 23T11: 42: 53.345Z',
                    updatedAt: '2019 - 04 - 23T11: 42: 53.345Z'
                },
                updater:
                {
                    id: 1,
                    name: 'Dr. Jimmie',
                    createdAt: '2019 - 04 - 23T11: 42: 53.345Z',
                    updatedAt: '2019 - 04 - 23T11: 42: 53.345Z'
                }
            },
        }]
}

What is actually happening?

(node:6746) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'includes' of undefined
    at model.set (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3473:80)
    at model.set (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3444:18)
    at model._initValues (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:169:10)
    at new Model (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:114:10)
    at new patientDeviceAssociation (/home/nic/playground/sequelize/node_modules/sequelize/lib/sequelize.js:357:19)
    at Function.build (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:2140:12)
    at model._setInclude (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3607:85)
    at model.set (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3475:14)
    at model.set (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3444:18)
    at model._initValues (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:169:10)
    at new Model (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:114:10)
    at new patient (/home/nic/playground/sequelize/node_modules/sequelize/lib/sequelize.js:357:19)
    at Function.build (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:2140:12)
    at valueSets.map.values (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:2160:41)
    at Array.map (<anonymous>)
    at Function.bulkBuild (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:2160:22)
    at model._setInclude (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3610:83)
    at model.set (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3475:14)
    at setKeys (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3432:20)
    at model.set (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:3440:13)
    at model._initValues (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:169:10)
    at new Model (/home/nic/playground/sequelize/node_modules/sequelize/lib/model.js:114:10)

This seems to be the line that caused the issue

Environment

Dialect:

  • mysql
  • postgres 10.6 (docker postgres:10.6)
  • sqlite
  • mssql
  • any

Dialect library version: pg-native 3.0.0, pg 7.10.0 Database version: 10.6 Sequelize version: 5.7.4 Node Version: 8.12.0 OS: Arch Linux (both native and within docker node:carbon-alpine)

Tested with latest release:

  • No
  • Yes, specify that version: 5.7.4

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:20 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
cristianszwarccommented, Apr 25, 2020

@papb thanks for your amazing work with the documentation.

might you please elaborate on “but it requires a little ‘trick’”? already went through your PR multiple times but still trying to find out how to include associations to the linking/through record.

thanks!

5reactions
eperezfcommented, Nov 29, 2020

I’m having the same issue. The StackOverflow issue is not related.

@papb where can we see the solution?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Rails: include nested through association - Stack Overflow
This builds an array of store hashes, each store hash has an array of products, and the hash is converted to json. Share....
Read more >
Eager Loading - Sequelize
By default, associations are loaded using a LEFT OUTER JOIN - that is to say it only includes records from the parent table....
Read more >
Active Record Associations - Ruby on Rails Guides
Active Record AssociationsThis guide covers the association features of Active Record.After reading this guide, you will know: How to declare associations ...
Read more >
How a has_many :through association works in practice
“I'm using a has_many :through relationship which appears to be working. I now need a form that I can render to have users...
Read more >
Has many through associations in Ruby on Rails - YouTube
In this episode we'll talk about how to use has many through associations with a join table instead of a has and belongs...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found