3
votes

I am having this weird behavior. I have a User model, and a Client model. User has many Clients. I am using this docs: http://docs.sequelizejs.com/manual/tutorial/associations.html

When I run the server, Sequelize throws TypeError: User.hasMany is not a function

Node version: 8.9.1
Dialect: postgres
Database version: Postgres 10
Sequelize version: 4.22.15

The following files are all in the same folder

user.js model

const Sequelize = require('sequelize');
const db = require('../index.js'); //This is an instance of new Sequelize(...)

const tableName = 'users';

const User = db.define('user', {
  firstName: {
    type: Sequelize.STRING(50),
    allowNull: false,
    validate: {
      notEmpty: true
    }
  },
  lastName: {
    type: Sequelize.STRING(50),
    allowNull: false,
    validate: {
      notEmpty: true
    }
  },
  username: { //Username will be the email
    type: Sequelize.STRING(80),
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true
    }
  },
  password: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: {
      notEmpty: true
    }
  },
  isAdmin: {
    type: Sequelize.BOOLEAN,
    allowNull: false,
    defaultValue: false
  },
  isActive: {
    type: Sequelize.BOOLEAN,
    allowNull: false,
    defaultValue: false
  }

}, { tableName });

module.exports = User;

client.js model

'use strict'

const Sequelize = require('sequelize');
const db = require('../index.js');

const instanceMethods = {
  toJSON() {
    const values = Object.assign({}, this.get());

    return values;
  },
};

const Client = db.define('clients', {
  ibid: {
    type: Sequelize.BIGINT,
    allowNull: true,
    defaultValue: null
  },
  firstName: {
    type: Sequelize.STRING(50),
    allowNull: false,
    validate: {
      notEmpty: true
    }
  },
  lastName: {
    type: Sequelize.STRING(50),
    allowNull: false,
    validate: {
      notEmpty: true
    }
  },
  agreementSigned: {
    type: Sequelize.BOOLEAN,
    allowNull: false,
    defaultValue: false
  },
  totalBalance: {
    type: Sequelize.DECIMAL(11,2),
    allowNull: true,
    defaultValue: null
  },
  currentAllocation: {
    type: Sequelize.STRING,
    allowNull: true,
    defaultValue: null
  }

}, { instanceMethods });

module.exports = Client;

index.js models

'use strict';

const User = require('./user')
const Client = require('./client');

User.hasMany(Client);
Client.belongsTo(User);

module.exports = {User, Client};
1
In the user.js you are not exporting user module.exports = User;Molda
@Molda I am sorry, I didn't copy the final of the file but yes, I am exporting the User model correctlyLeandro Echevarria

1 Answers

2
votes

In the index.js, you haven't exported the new sequelize instance you have initialised and thus it is not available to the client.js and user.js! the define function works on the sequelize instance object that you have created!

Also there is a circular dependency in the project which might create problem!

I tried your code and changed the structure and it works now! There might be another structures possible too but this one works for me!

1) Don't create a new instance of sequelize in the index.js rather create another file that will serve as initialisation for the sequelize instance!

sequelize_index.js (I have used this file for creating a base instance and then using this base instance in both the client and user models)

const Sequelize = require('sequelize');
const dbconfig=require('./dbconfig.json');

const sequelize = new Sequelize('postgres://' + dbconfig.USER + ":" +     dbconfig.PASSWORD + "@" + dbconfig.HOST + ":5432/" + dbconfig.DB, {
host: dbconfig.HOST,
dialect: dbconfig.DIALECT,
pool: {
    min: 0,
    max: 5,
    idle: 1000
     }
});

 module.exports={sequelize};

2) The client.js would look something like this!

'use strict'
const Sequelize = require('sequelize');

const sequelize=require('./sequelize_index').sequelize;
const db = require('./index.js');

const instanceMethods = {
    toJSON() {
        const values = Object.assign({}, this.get());

        return values;
    },
};

const Client = sequelize.define('clients', {
    ibid: {
        type: Sequelize.BIGINT,
        allowNull: true,
        defaultValue: null
    },
    firstName: {
        type: Sequelize.STRING(50),
        allowNull: false,
        validate: {
            notEmpty: true
        }
    },
    lastName: {
        type: Sequelize.STRING(50),
        allowNull: false,
        validate: {
            notEmpty: true
        }
    },
    agreementSigned: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: false
    },
    totalBalance: {
        type: Sequelize.DECIMAL(11,2),
        allowNull: true,
        defaultValue: null
    },
    currentAllocation: {
        type: Sequelize.STRING,
        allowNull: true,
        defaultValue: null
    }

}, { instanceMethods });

module.exports = Client;

3) User.js

const Sequelize = require('sequelize');
const sequelize=require('./sequelize_index').sequelize;
const db = require('./index.js'); //This is an instance of new Sequelize(...)

const tableName = 'users';

const User = sequelize.define('user', {
    firstName: {
        type: Sequelize.STRING(50),
        allowNull: false,
        validate: {
            notEmpty: true
        }
    },
    lastName: {
        type: Sequelize.STRING(50),
        allowNull: false,
        validate: {
            notEmpty: true
        }
    },
    username: { //Username will be the email
        type: Sequelize.STRING(80),
        allowNull: false,
        unique: true,
        validate: {
            isEmail: true
        }
    },
    password: {
        type: Sequelize.STRING,
        allowNull: false,
        validate: {
            notEmpty: true
        }
    },
    isAdmin: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: false
    },
    isActive: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: false
    }

}, { tableName });

module.exports = User;

4) index.js

'use strict';
const sequelize = require('./sequelize_index').sequelize;
const User = require('./user')
const Client = require('./client');


User.hasMany(Client);
Client.belongsTo(User);

sequelize.sync({force: false}).then(function () {
    console.log("Database Configured");
});
module.exports = {User, Client};

After running the index.js, the database would be created!