sequelize: Cannot read property 'name' of undefined when associating with hasMany
Issue Description
I have User and Message models, and I am attempting to associate them. User is supposed to have many Message and Message belongs to User. What’s happening is that hasMany is throwing some errors I cannot figure out why, and what’s more maddening is that I had already used a few months ago the way things are now, but this time it decided to not work.
StackOverflow / Slack attempts
Additional context
User migration and class:
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('users', {
      id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true,
        allowNull: false
      },
      username: {
        type: Sequelize.STRING,
        unique: true,
        allowNull: false
      },
      first_name: {
        type: Sequelize.STRING,
        allowNull: false
      },
      middle_name: {
        type: Sequelize.STRING
      },
      last_name: {
        type: Sequelize.STRING,
        allowNull: false
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false
      }
    })
  },
  down: queryInterface => {
    return queryInterface.dropTable('users')
  }
}
import Sequelize, { Model } from 'sequelize'
class User extends Model {
  static init(sequelize) {
    super.init(
      {
        username: Sequelize.STRING,
        first_name: Sequelize.STRING,
        middle_name: Sequelize.STRING,
        last_name: Sequelize.STRING
      },
      {
        sequelize
      }
    )
    return this
  }
  static associate(models) {
    this.hasMany(models.Message)
  }
  static async findByUsername(username) {
    return User.findOne({ where: { username } })
  }
}
export default User
Message migration and model:
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('messages', {
      id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true,
        allowNull: false
      },
      user_id: {
        type: Sequelize.INTEGER,
        references: { model: 'users', key: 'id' },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
        allowNull: false
      },
      content: {
        type: Sequelize.STRING,
        allowNull: false
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false
      }
    })
  },
  down: queryInterface => {
    return queryInterface.dropTable('messages')
  }
}
import Sequelize, { Model } from 'sequelize'
class Message extends Model {
  static init(sequelize) {
    super.init(
      {
        user_id: Sequelize.INTEGER,
        content: Sequelize.STRING
      },
      {
        sequelize
      }
    )
    return this
  }
  static associate(models) {
    this.belongsTo(models.User, { foreignKey: 'user_id' })
  }
}
export default Message
Database class where things get initialized:
import Sequelize from 'sequelize'
import config from '../config/database'
import models from '../models'
class Database {
  constructor() {
    this.init()
  }
  init() {
    this.connection = new Sequelize(config)
    Object.keys(models).forEach(model => {
      models[model].init(this.connection)
      if ('associate' in models[model]) {
        models[model].associate(models)
      }
    })
  }
}
export default new Database()
models.js file where the models are imported and exported (GraphQL context):
import User from './User'
import Message from './Message'
export default {
  User,
  Message
}
Error when starting the server with npm start:
this.as = this.target.options.name.plural;
                                    ^
TypeError: Cannot read property 'name' of undefined
    at new HasMany (/home/gabriel/Workspace/apollo-server-sample/node_modules/sequelize/lib/associations/has-many.js:51:37)
    at Function.hasMany (/home/gabriel/Workspace/apollo-server-sample/node_modules/sequelize/lib/associations/mixin.js:34:25)
    at Function.associate (/home/gabriel/Workspace/apollo-server-sample/src/models/User.js:21:10)
    at forEach (/home/gabriel/Workspace/apollo-server-sample/src/database/index.js:17:23)
    at Array.forEach (<anonymous>)
    at Database.init (/home/gabriel/Workspace/apollo-server-sample/src/database/index.js:13:25)
    at new Database (/home/gabriel/Workspace/apollo-server-sample/src/database/index.js:7:10)
    at Object.<anonymous> (/home/gabriel/Workspace/apollo-server-sample/src/database/index.js:23:16)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Module._compile (/home/gabriel/Workspace/apollo-server-sample/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Object.newLoader [as .js] (/home/gabriel/Workspace/apollo-server-sample/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Module.require (internal/modules/cjs/loader.js:849:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/gabriel/Workspace/apollo-server-sample/src/app.js:7:1)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Module._compile (/home/gabriel/Workspace/apollo-server-sample/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Object.newLoader [as .js] (/home/gabriel/Workspace/apollo-server-sample/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:812:32)
[nodemon] app crashed - waiting for file changes before starting...
Issue Template Checklist
Is this issue dialect-specific?
- No. This issue is relevant to Sequelize as a whole.
 - Yes. This issue only applies to the following dialect(s): XXX, YYY, ZZZ
 - I don’t know.
 
Would you be willing to resolve this issue by submitting a Pull Request?
- Yes, I have the time and I know how to start.
 - Yes, I have the time but I don’t know how to start, I would need guidance.
 - No, I don’t have the time, although I believe I could do it if I had the time…
 - No, I don’t have the time and I wouldn’t even know how to start.
 
About this issue
- Original URL
 - State: closed
 - Created 5 years ago
 - Comments: 15 (5 by maintainers)
 
FIGURED IT OUT
@mfgabriel92 and I had the same flaw in our database initialization code.
If one of the dependent models has not been init-ed, then any calls to association methods will fail. You can fix this with one loop to call
init()and another to callassociate, i.e.Confirmed the failure in the SSCCE by writing in a similar structure. Thanks @papb for helping me troubleshoot.
I have the same problem the message is node_modules/sequelize/lib/associations/has-one.js:31 this.as = this.target.options.name.singular; ^ TypeError: Cannot read property ‘name’ of undefined
I have no idea what to do, i tried a lot of different things, but nothing works in this case.
If i found the error ill come back here to say how fix!
Under the use case provided by the SSCCE, yes.
Now I have to figure out how my usage differs from this bare bones case, and if the root cause is misuse on my part, or a valid use case that is not tested by your reproduction test harness.