3

I am trying to associate two tables in Sequelize but I am getting the SequelizeEagerLoadingError that one table is not associated to another despite trying all the available fixes on this platform.

I have two tables, User and Item.

User (user.js)

const User = dbconnection.sequelize.define('users', {
    id:  { type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true},
    name: {
        type:  Sequelize.STRING(80),
        allowNull: false
    },
    email: {
        type:  Sequelize.STRING(120),
        allowNull: false,
        unique: true
    },
    dob: {
        type: Sequelize.DATEONLY,
        allowNull: false
    },
    password: {
        type:  Sequelize.STRING(256),
        allowNull: false
    }

});

User.associate = models => {
    User.hasMany(models.Item, { as: 'items',foreignKey: 'user_id' })
}

dbconnection.sequelize.sync({ force: false })
    .then(() => {
        //console.log('Table created!')
    });

module.exports = {
    User
};

Item (item.js)

const Item = dbconnection.sequelize.define('items', {
    id:  { type: Sequelize.INTEGER, unique: true, autoIncrement: true, primaryKey: true},
    item: {
        type: Sequelize.STRING(80),
        allowNull: true
    },
    item_type: {
        type: Sequelize.STRING(10),
        allowNull: false
    },
    comment: {
        type: Sequelize.STRING(1000),
        allowNull: true
    },
    user_id: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: { model: 'users', key: 'id' }
    },
});

Item.associate = models => {
    Item.belongsTo(models.User, { as: 'users',foreignKey: 'user_id' })
}

dbconnection.sequelize.sync({ force: false })
    .then(() => {
        // console.log('Table created!')
    })
});

module.exports = {
    Item
};

User hasMany(Item) while Item belongsTo(User) as shown above.

However, when I make a query to the Item table (as below),

const usersdb = require('./userdb')
const itemsdb = require('./itemdb')

class ItemsController {
    static async getAllItems(req, res, next) {
        try{
            let allitems = await itemsdb.Item.findAll({
                include: [{
                    model: usersdb.User
                }]
            })
            return {items: allitems, status: true}
        }
        catch (e) {
            return {items: e, status: false}
        }
    }
}

module.exports = ItemsController;

I get the SequelizeEagerLoadingError that "users is not associated to items!"

I have tried all the available fixes including this and this among others but to no success.

Rotiken Gisa
  • 380
  • 2
  • 12
  • You should use an alias you defined in an Item model for user, also I think you should use alias items instead of user in a User model, it makes a more sense to me and maybe problem is a duplicity in aliases. Last thing is you should use a synch method once after all associations not in all models, it is not a good approach. – l2ysho Jun 23 '19 at 21:05
  • @RichardSolár I have corrected the aliases but is still not working. – Rotiken Gisa Jun 24 '19 at 07:07
  • Can you reproduce it in some example code and share a repo? – l2ysho Jun 24 '19 at 11:23
  • I have finally found a workaround. First, I dropped the tables. Second, I generated migrations and models using the " sequelize model:create --name ModelName --attributes columnName:columnType " command. I then used the generated models to associate the two tables just as I had done earlier. Lastly, I ran the " sequelize db:migrate " command to create the tables and on running the query, IT WORKED! – Rotiken Gisa Jun 25 '19 at 09:17
  • so it looks a sync method in model was a problem – l2ysho Jun 25 '19 at 11:12
  • sure, was also thinking the same – Rotiken Gisa Jun 25 '19 at 12:08

1 Answers1

0

I have finally found a workaround. First, I dropped the tables and discarded the model definitions. Second, I generated migrations and models using the sequelize model:create --name ModelName --attributes columnName:columnType command. I then used the generated models to associate the two tables just as I had done earlier. Lastly, I ran the sequelize db:migrate command to create the tables and on running the query, it worked!

Earlier, I was creating the models manually. I was also creating the tables using the sequelize.sync({force: false/true}) command after loading the models.

User Model (user.js)

'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    email: {
        type:  DataTypes(120),
        allowNull: false,
        unique: true
    },
    dob: {
        type: DataTypes.DATEONLY,
        allowNull: false
    },
    password: {
        type:  DataTypes.STRING(256),
        allowNull: false
    }
  }, {});
  User.associate = function(models) {
    User.hasMany(models.Item, {as: 'Item', foreignKey: 'user_id'})
  };
  return User;
};

Item model (item.js)

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Item = sequelize.define('Item', {
    item: {
      type: DataTypes.STRING(80),
      allowNull: true
    },
    item_type: {
      type: DataTypes.STRING(10),
      allowNull: false
    },
    comment: {
      type: DataTypes.STRING(1000),
      allowNull: true
    },
    user_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: { model: 'User', key: 'id' }
    }
  }, {});
  Item.associate = function(models) {
    Item.belongsTo(models.User, { as: 'User',foreignKey: 'user_id' })
  };
  return Item;
};

Query (queryitem.js)

const Item = require('../models').Item
const User = require('../models').User

class ItemsController {
    static async getAllItems() {
        try{
            let allitems = await Item.findAll({
                include: [{
                    model: User,
                    as: 'User'
                }]
            })
            return {items: allitems, status: true}
        }
        catch (e) {
            return {items: e, status: false}
        }
    }
}

module.exports = ItemsController;

Rotiken Gisa
  • 380
  • 2
  • 12