Toby Tremayne
Toby Tremayne

Reputation: 135

Sequelize eager loading association with through table

I've been through several questions on the site but I still can't see what I'm doing wrong here, so any help would be greatly appreciated.

I'm getting the error:

Organization (organizations) is not associated to User!

Org Model:

module.exports = function (sequelize, DataTypes) {
    return sequelize.define('Organization', {

        organizationID: {
            primaryKey: true,
            type: DataTypes.INTEGER(11),
            allowNull: false,
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false,
        },
        description: {
            type: DataTypes.STRING,
            allowNull: true,
        }
    },
    {
        tableName: "spa_vOrganization",
        freezeTableName: true,
        classMethods: {
            associate: function (models) {
                Organization.hasMany(models.User, {
                    as: 'users',
                    through: models.User_Tenant_Organization,
                    foreignKey: 'organizationID'
                });
            }
        },
    });
};

User Model:

module.exports = function (sequelize, DataTypes) {
    return sequelize.define('User', {
            userID: {
                primaryKey: true,
                type: DataTypes.INTEGER(11),
                allowNull: false,
            },
            password: {
                type: DataTypes.STRING,
                allowNull: false,
            },
            email: {
                type: DataTypes.STRING,
                allowNull: false,
            }
        },
        {
            tableName: "spa_User",
            freezeTableName: true,
            classMethods: {
                associate: function(models) {
                    User.hasMany(models.Organization, { as: "organizations", through: models.User_Tenant_Organization, foreignKey: 'userID'});
                }
            }
        }
    );
};

Matrix table model:

module.exports = function (sequelize, DataTypes) {
    return sequelize.define('User_Tenant_Organization', {

        userTenantOrganizationID: {
            primaryKey: true,
            type: DataTypes.INTEGER(11),
            allowNull: false,
        },
        userID: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
        },
        organizationID: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
        },
        tenantID: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
        },
    },
    {
        tableName: "spa_User_Tenant_Organization",
        freezeTableName: true,
    });
};

What I'm trying to do is just pull back a user with their organizations eagerly loaded. Here's what I'm using:

models.User.findOne({where: {
        email: body.email
    }, include: [ {model:models.Organization, as: 'organizations'}]}).complete( function (err, user)     {
// do something with the user
}

I've tried with and without foreignKey definitions on both User and Organization, nothing makes any difference. I'm obviously misunderstanding something about the associations. Can anyone tell me where I'm going wrong please?

Upvotes: 1

Views: 3343

Answers (1)

Toby Tremayne
Toby Tremayne

Reputation: 135

I found the problem. The associations in the above code are actually correct - what was failing was my models/index.js, which had been automatically generated by the yeoman generator-angular-express-sequelize

index.js was looping through the model files, importing them into the sequelize object and storing a copy in an array db[], then trying to run the classMethod associate(), but it was calling models.options.associate() instead of models.associate():

Object.keys(db).forEach(function (modelName) {
    if (db[modelName].options.hasOwnProperty('associate')) {
        db[modelName].options.associate(db);
    }
});

I've fixed that by removing the ".options" and everything works fine.

Pull request to fix the problem is here for reference: https://github.com/rayokota/generator-angular-express-sequelize/pull/7

Upvotes: 1

Related Questions