2

I'm trying to create many to many relationship using Sequelize + nodeJs using existing MySQL Database :

Below is my tables : - "usr" Table : usr_id (PK) - Intermediate "usr_role" : usr_id, role_id - "role" table : role_id

This is my models "User" Models:

"use strict";
var bcrypt = require('bcryptjs');

 module.exports = function(sequelize, DataTypes) {

  var User = sequelize.define('User', {
    usrid  : {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true,
        allowNull: false,
        field:'usr_id'
    },
    name :{
        type: DataTypes.STRING,
        allowNull: false,
        field:'usr_name'
    },

  }, {
    timestamps: false,
    freezeTableName: true,
    tableName: 'usr',
    name:'User',
    underscored:'true',

    classMethods: {
      associate:function(models){
        User.belongsToMany(models.Role, { through: 'UserRole', foreignKey:'usr_id', as:'UserRoles'});
      }

    }
  }
);
  return User;
};

"Role" models

module.exports = function(sequelize, DataTypes) {
var Role = sequelize.define('Role', {
  id  : {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true,
      allowNull: false,
      field:'role_id'
  },
  name :{
      type: DataTypes.STRING,
      allowNull: false,
      field:'role_name'
  },

},{
  timestamps: false,
  freezeTableName: true,
  tableName: 'role_ref',
  underscored:'true',

  classMethods: {
    associate:function(models){
      Role.belongsToMany(models.User, {
        through: 'UserRole',
        foreignKey:'role_id'});
     }
  }
}
)
return Role;
};
E:\nodejsWS\learn\node_modules\inflection\lib\inflection.js:795
var str_path = str.split( '::' );
                    ^
TypeError: Cannot read property 'split' of undefined
at Object.inflector.underscore 
(E:\nodejsWS\learn\node_modules\inflection\lib\inflection.js:795:25)
at Object.module.exports.underscoredIf 
(E:\nodejsWS\learn\node_modules\sequelize\lib\utils.js:28:27)
at new BelongsToMany (E:\nodejsWS\learn\node_modules\sequelize
\lib\associations\belongs-to-many.js:134:15)
at Mixin.belongsToMany 
(E:\nodejsWS\learn\node_modules\sequelize\lib\associations
\mixin.js:264:21)
at sequelize.define.classMethods.associate 
(E:\nodejsWS\learn\models\Role.js:29:12)
at E:\nodejsWS\learn\models\index.js:50:21

this is my index.js

// Import models
  fs
    .readdirSync(__dirname)
    .filter(function(file) {
      return (file.indexOf(".") !== 0) && (file !== "index.js");
    })
    .forEach(function(file) {
      var model = sequelize.import(path.join(__dirname, file));
      db[model.name] = model;
    });

//associate models
  Object.keys(db).forEach(function(modelName) {
    if ("associate" in db[modelName]) {
      console.log(db);
      db[modelName].associate(db);
    }
  });

Line 50 refer to db[modelName].associate(db), that cause the error.

Can somebody please guide me what's i'm doing wrong. Do i need to manually create intermediate Models 'UserRole'. Your help is very much appreciated. Thanks.

1 Answers1

0

You need to specify the actual intermediate table's name in the belongsToMany config, or define the model UserRole. Also, unless your intermediate table has the fields, you'll probably also want to specify timestamps: false as well. So, for example:

Role.belongsToMany(models.User, {
    through: 'usr_role',
    foreignKey:'role_id',
    timestamps: false
});

This will cause sequelize to use that table in the queries it builds without needing a model defined, and will prevent it from requesting the timestamp fields from either the User table or the intermediate.

Will
  • 2,163
  • 1
  • 22
  • 22
  • Thanks for your respond. I have tried to use your solution but the error "TypeError: Cannot read property 'split' of undefined" still exists. I'm using sequelize version 3.23.6. Thanks – user4661864 Aug 18 '16 at 07:03