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.