Trying to setup a simple association in sequelize for my apollo graphql api. I have two tables: user
and role
. Each user has a role_id
column that references the primary keys in the role
table.
Whenever I query:
{
users{
id,
email,
role{
id
}
},
}
I receive the following error: "Cannot return null for non-nullable field User.role.",
I am new to sequelize/apollo, but am unable to see where I am going wrong.
models/user.js
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
User.belongsTo(models.Role);
}
};
User.init({
email: DataTypes.STRING,
password: DataTypes.STRING,
}, {
sequelize,
tableName: 'user',
schema: 'auth',
modelName: 'User',
timestamps: false,
underscored: true,
});
return User;
};
models/role.js
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Role extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
Role.hasMany(models.User)
}
};
Role.init({
name: DataTypes.STRING,
isDefault: {
type: DataTypes.BOOLEAN,
field: 'is_default'
},
}, {
sequelize,
tableName: 'role',
schema: 'auth',
modelName: 'Role',
timestamps: false,
underscored: true,
});
return Role;
};
The models get associated in my: models/index.js
with the following snippet:
...
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
// sync models - modifies the database to match every model
sequelize.sync({ alter: true, match: /-apollo$/ })
...
And here is my: resolvers/user.js
module.exports = {
Query: {
users: async (parent, args, { models }) => {
return await models.User.findAll({ include: [{model: models.Role}] });
},
user: async (parent, { id }, { models }) => {
return await models.User.findByPk(id);
},
},
};
Any help would be much appreciated!
Edit: I created a new database and added sequelize.sync()
to my models/index.js
to ensure that this is not caused by some error in my database setup.
Found the solution. My issue was that sequelize automaticly names the association, which in my case was unexpected and so my schema didn't match the actual name of the association which resulted in nulls.
To fix this I added the as: "something"
prop to my association:
resolvers/user.js
module.exports = {
Query: {
users: async (parent, args, { models }) => {
return await models.User.findAll({ include: [{model: models.Role, as: 'role'}] });
},
user: async (parent, { id }, { models }) => {
return await models.User.findByPk(id);
},
},
};