question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot read property 'name' of undefined when associating with hasMany

See original GitHub issue

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

https://stackoverflow.com/questions/58934011/sequelize-typeerror-cannot-read-property-name-of-undefined-between-a-1-rel

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.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:15 (5 by maintainers)

github_iconTop GitHub Comments

7reactions
bobspacecommented, Jan 16, 2020

FIGURED IT OUT

@mfgabriel92 and I had the same flaw in our database initialization code.

Object.keys(models).forEach(model => {
  models[model].init(this.connection)

  if ('associate' in models[model]) {
    models[model].associate(models)
   }
 })

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 call associate, i.e.

Object.keys(models).forEach(model => {
  models[model].init(this.connection)
 })

Object.keys(models).forEach(model => {
  if ('associate' in models[model]) {
    models[model].associate(models)
  }
})

Confirmed the failure in the SSCCE by writing in a similar structure. Thanks @papb for helping me troubleshoot.

2reactions
silveiratalitacommented, Dec 16, 2019

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!

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeError: Cannot read property 'hasOne' of undefined
You're defining it with a different name. Change this: var ADataMembers = sequelize.define('data_members', { // ^ this is the problem.
Read more >
TypeError: Cannot read property 'hasMany' of undefined" in ...
Coding example for the question "TypeError: Cannot read property 'hasMany' of undefined" in TypeScript-sequelize.js.
Read more >
sequelize/sequelize - Gitter
... have a model called users.js , but I every time i want to run the app , I get "TypeError: Cannot read...
Read more >
Associations
The A.hasMany(B) association means that a One-To-Many relationship exists between A and B , with the foreign key being defined in the target ......
Read more >
Associations - Linking Tables Together - 3.10
The four association types in CakePHP are: hasOne, hasMany, belongsTo, ... propertyName: The property name that should be filled with data from the ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found