I am trying to implement a three table solution for project/post tags.
These are my models:
projects.model.js
const Projects = db.sequelize.define (
'Projects',
{
project_id: {
type: Sequelize.DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
creator_id: {
type: Sequelize.DataTypes.INTEGER,
allowNull: false,
references: {
model: User,
key: 'id'
}
},
project_title: {
type: Sequelize.DataTypes.STRING,
allowNull: false
},
project_description: {
type: Sequelize.DataTypes.STRING,
allowNull: false
},
creation_date: {
type: Sequelize.DataTypes.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
},
last_updated_date: {
type: Sequelize.DataTypes.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
}
}, {
timestamps: false
}
)
export default Projects
project-tags.model.js
const ProjectTags = db.sequelize.define(
'Project Tags',
{
id: {
type: Sequelize.DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
project_id: {
type: Sequelize.DataTypes.INTEGER,
allowNull: false,
references: {
model: Projects,
key: 'project_id'
}
},
project_tag_id: {
type: Sequelize.DataTypes.INTEGER,
allowNull: false,
references: {
model: Tags,
key: 'id'
}
},
}, {
timestamps: false
});
Tags.belongsToMany(Projects, { through: ProjectTags, foreignKey: 'project_id', as: 'tags' });
Projects.belongsToMany(Tags, { through: ProjectTags, foreignKey: 'project_tag_id', as: 'tags' });
export default ProjectTags
tags.model.js
const Tags = db.sequelize.define(
'Tags',
{
id: {
type: Sequelize.DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
tag: {
type: Sequelize.DataTypes.STRING,
allowNull: false
}
}, {
timestamps: false
});
export default Tags
And I am eager loading it like that:
const projects = Projects.findAll({
attributes: ['project_id','creator_id','project_title','project_description','creation_date','last_updated_date'],
include: [{
model: Tags,
as: 'tags',
attributes: ['tag'],
}]
})
.catch(error => {
throw new Error(error);
})
return projects;
It returns the project data fine, but tags is an empty array although the table is not empty and the references seem to be correct. What am I missing here?
You mixed up the foreign key options in associations. foreignKey
option on belongsToMany
should indicate the field that links the main model on which you call belongsToMany
and not the one that you pass as the first argument. And of course you need to indicate different aliases (they should correspond to the passed model (as the first argument):
Tags.belongsToMany(Projects, { through: ProjectTags, foreignKey: 'project_tag_id',
otherKey: 'project_id', as: 'projects' });
Projects.belongsToMany(Tags, { through: ProjectTags, foreignKey: 'project_id', otherKey: 'project_tag_id', as: 'tags' });
If you want to indicate the key for the passed model you need to use otherKey
option next to foreignKey
option.