Reputation: 122
I'm having problems to use the findAll() method with associations from Sequelize.
I have two models: Posts and Authors (an author has many posts and one post has one author), that I have created with Sequelize-cli and then through the migration command npx sequelize db migrate:all
i have created them in mysql. To keep things organized, I have the associations between the models in another migration file (created with npx sequelize init:migrations
, after all the models already existent), so my code looks like this:
AUTHOR MODEL
'use strict';
module.exports = (sequelize, DataTypes) => {
const Author = sequelize.define('Author', {
authorName: {
type: DataTypes.STRING,
validate: {
is: ["^[a-z]+$",'i'],
}
},
biography: {
type: DataTypes.TEXT,
validate: {
notEmpty: true,
}
}
}, {});
Author.associate = function(models) {
Author.hasMany(models.Post);
};
return Author;
};
POST MODEL
'use strict';
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('Post', {
title: {
type: DataTypes.STRING,
validate: {
is: ["^[a-z]+$",'i'],
notEmpty: true,
},
},
content: {
type: DataTypes.TEXT,
validate: {
notEmpty: true,
},
},
likes: {
type: DataTypes.INTEGER,
defaultValue: 0,
validate: {
isInt: true,
},
},
}, {});
Post.associate = function(models) {
// associations can be defined here
};
return Post;
};
ASSOCIATIONS FILE (MIGRATION) (showing only parts that matter)
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction(t => {
return Promise.all([
queryInterface.addColumn('Posts','AuthorId', {
type: Sequelize.INTEGER,
references: {
model: 'Authors',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
queryInterface.addColumn('Posts', 'ImagesId', {
type: Sequelize.INTEGER,
references: {
model: 'Images',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
queryInterface.addColumn('Posts', 'CategoryId', {
type: Sequelize.INTEGER,
references: {
model: 'Categories',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
]);
});
This is working fine apparently, since in Mysql-Workbench it shows me the following:
But, when I try to use the findAll() like this:
const { Post, Author } = require('../models/index');
function(response) {
Post.findAll({
attributes: ['id', 'title', 'content', 'likes'],
include: {
model: Author,
}
})
.then(result => response.json(result))
.catch(error => response.send(`Error getting data. Error: ${error}`));
It gives me the following error:
SequelizeEagerLoadingError: Author is not associated to Post!
So, I dont know anymore how to proceed. I've been trying many others approaches, but all of then unsuccessfully. I read already many other questions here in StackOverFlow about how to solve this sort of problem, but those were unsuccessfully too.
Thanks in advance.
Upvotes: 0
Views: 2396
Reputation: 299
Summarizing this documentation we have the following:
If you have these models:
const User = sequelize.define('user', { name: DataTypes.STRING });
const Task = sequelize.define('task', { name: DataTypes.STRING });
And they are associated like this:
User.hasMany(Task);
Task.belongsTo(User);
You can fetch them with its associated elements in these ways:
const tasks = await Task.findAll({ include: User });
Output:
[{
"name": "A Task",
"id": 1,
"userId": 1,
"user": {
"name": "John Doe",
"id": 1
}
}]
And
const users = await User.findAll({ include: Task });
Output:
[{
"name": "John Doe",
"id": 1,
"tasks": [{
"name": "A Task",
"id": 1,
"userId": 1
}]
}]
Upvotes: 1
Reputation: 58533
You need to define the association for Post also as you are querying upon Post model
Post.associate = function(models) {
Post.belongsTo((models.Author);
};
You need to add an association from both ends, Post -> Author
and Author -> Post
, this way you will never stuck in this kind of error.
Upvotes: 1