one-to-many relationship with sequelize - node.js

I have 2 tables, users and users_signature where the signature takes several applications and I need to make a select according to the application.
Models:
user
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = require('./user_has_signature');
const Usuario = database.define('usuario', {
usu_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
usu_rg: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User.hasMany(User_has_signature, {as: 'user_has_signature'});
module.exports = User;
User_has_signature
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = database.define('user_has_signature', {
usu_has_signature_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
user_usu_id: {
type: Sequelize.STRING,
},
signature_aplicativo_signature_aplicativo_id: {
type: Sequelize.STRING,
},
signature_type_signature_type_id: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User_has_signature.associate = (models) => {
User_has_signature.belongsTo(models.User,
{ foreignKey: 'user_usu_id', as: 'users' });
};
module.exports = User_has_signature;
Controller
UserController
const User = require("../../model/user/user")
const User_has_signature = require("../../model/user/user_has_signature")
async index(req, res){
const user = await User.findAll({
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
through: {
where: {signature_ttype_signature_type_id: 3}
}
}]
})
res.status(200).json(user)
return
}
The error that is returning to me in the terminal is: (node:15168)
UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError:
user_has_signature is associated to usuario using an alias. You must
use the 'as' keyword to specify the alias within your include
statement

I think you have to specify the alias you have given when writing your query :
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
as : 'users'
through: {
where: {signature_ttype_signature_type_id: 3}
}]
Either way I'm using Sequelize more in Typescript, so I'm not sure of the syntax.
The way it handles One to Many relationship isn't the clearest I've seen (Like Symfony or Spring)

Related

how to write migrations to add foreignkey to already existing tables in sequelize

I have this already created two tables called User and Profile.
This is how my model for User looks like..
const Sequelize = require("sequelize");
const db = require("../db");
const User = db.define("User", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: true,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validator: {
isEmail: true,
},
},
});
module.exports = User;
and model for Profile looks like..
const Sequelize = require("sequelize");
const User = require("./User");
const db = require("../db");
const Profile = db.define("Profile", {
image: {
type: Sequelize.STRING,
},
description: {
type: Sequelize.TEXT,
},
});
module.exports = Profile;
Now I want to define a one-to-one relationship between User and Profile such that user will recieve a profileId column.
so i am defining it like this
Profile.hasOne(User, {
foreignKey: {
allowNull: false,
},
});
User.belongsTo(Profile);
Now i am not able to figure out how to write migrations for the newly added foreign key
can anyone help me please..
Thanks.
I got the answer. for someone who is confused like me here is the answer
since the User table already exists, migrations for the foreignkey will look like this
module.exports = {
async up(queryInterface, Sequelize) {
return await queryInterface.addColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
async down(queryInterface, Sequelize) {
return await queryInterface.removeColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
};
the Users in addColumn and removeColumn is the name of the table in which foreignkey was added.
the ProfileId is the name for foreignkey which you would have specified in hasOne.
hope this helps..

Sequelize model field that I did not add

I have a user, role and their relation model, when I want to insert into the relation model I get this error:
error: column "userUserId" of relation "roles_users_relationships" does not exist.
Can you help with this error?
(sorry if I wrote something wrong, this is my first question on )
This is how my model looks
Role model:
const Schema = (sequelize, DataTypes) => {
const table = sequelize.define(
"roles", {
role_id: {
type: DataTypes.UUID,
defaultValue: sequelize.literal("uuid_generate_v4()"),
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
}
}, {
timestamps: false
}
);
table.associate = function (models) {
table.belongsToMany(models.users, {
through: "roles_users_relationship",
foreignKey: "role_id",
});
};
return table;
};
Users model:
const Schema = (sequelize, DataTypes) => {
const table = sequelize.define(
"users", {
user_id: {
type: DataTypes.UUID,
defaultValue: sequelize.literal("uuid_generate_v4()"),
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: true,
}
}, {
timestamps: false
}
);
table.associate = function (models) {
table.belongsTo(models.roles, {
through: "roles_users_relationship",
foreignKey: "user_id",
});
};
return table;
};
Roles Users relationship model:
const Schema = (sequelize, DataTypes) => {
const table = sequelize.define(
"roles_users_relationship", {
user_id: {
type: DataTypes.UUID,
allowNull: false,
},
role_id: {
type: DataTypes.UUID,
allowNull: false,
},
}, {
timestamps: false
}
);
return table;
};
In your through table you should add options in related table field:
references: {
model: User,
key: 'user_id'
}
Otherwise sequelize will do it automatically, like adding foreign key column in this way tableNamePrimaryKeyColumn in your case its 'userUserId'

Error: Sequelize Assosication called with something that's not a subclass of Sequelize.Model

Hi everyone I'm having an error "Error: Text.belongsTo called with something that's not a subclass of Sequelize.Model" when I add association of Sequelize in my model it called an error that what I call is not Sequelize Model.
Here is the code of my models, I try to create an association between Post model and Text model.
./Post.js
const { DataTypes } = require('sequelize');
const sequelize = require('../../db/sequelize.setup');
const Text = require('./Text');
const Post = sequelize.define(
'Post',
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
title: {
type: DataTypes.STRING(),
allowNull: false,
},
tags: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: true,
},
items: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: false,
},
author: {
type: DataTypes.INTEGER,
},
},
{
modelName: 'Post',
timestamps: true,
}
);
Post.hasMany(Text, {
as: 'Text',
foreignKey: 'post_id',
sourceKey: 'id',
});
module.exports = Post;
./Text.js
const { DataTypes } = require('sequelize');
const sequelize = require('../../db/sequelize.setup');
const Post = require('./Post');
const Text = sequelize.define(
'Text',
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
text: {
type: DataTypes.STRING(),
allowNull: false,
},
},
{
modelName: 'Text',
timestamps: true,
}
);
Text.belongsTo(Post, { as: 'Post', foreignKey: 'post_id', targetKey: 'id' });
module.exports = Text;
try to make an index.js file in your models folder and inside of it make your association like this
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.posts=require("./post.js")(sequlize,sequlize);
db.texts=require....
db.posts.hasMany(db.texts, { foreignKey: 'postId' });
db.texts.belongsTo(db.posts, { foreignKey: 'postId' });
and put the postId in text.js model

SequelizeEagerLoadingError 'Model 1' is not assoicated to 'Model 2'

I am using sequelize version:5.21.2, and has the following error: 'Tweet is not associated to User!'
Error: { SequelizeEagerLoadingError: Tweet is not associated to User!
at Function._getIncludedAssociation (D:\References\Youtube\Sequelize\sequelize-1-hour\node_modules\sequelize\lib\model.js:715:13)
at Function._validateIncludedElement (D:\References\Youtube\Sequelize\sequelize-1-hour\node_modules\sequelize\lib\model.js:619:53)
at options.include.options.include.map.include (D:\References\Youtube\Sequelize\sequelize-1-hour\node_modules\sequelize\lib\model.js:516:37)
at Array.map (<anonymous>)
I have two models
Tweet.js
const Sequelize = require('sequelize');
//sequelize comes from global.sequelize in connection.js
const Tweet = sequelize.define('Tweet', {
id: {
type: Sequelize.INTEGER(11),
allowNull: true,
autoIncrement: true,
primaryKey: true
},
userId: Sequelize.INTEGER(11),
content: Sequelize.STRING(300)
});
Tweet.associate = function(models) {
Tweet.belongsTo(models.User, { foreignKey: 'userId' });
};
module.exports = Tweet;
and User.Js
const Sequelize = require('sequelize');
//sequelize comes from global.sequelize in connection.js
const User = sequelize.define('User', {
id: {
type: Sequelize.INTEGER(11),
primaryKey: true
},
username: {
type: Sequelize.STRING(35),
},
passwd: {
type: Sequelize.STRING(20),
allowNull: false
}
});
User.associate = function(models) {
User.hasMany(models.Tweet);
};
module.exports = User;
and the code which throws error is
const users = await User.findAll({
where: { id: '1' },
include: [Tweet]
}).catch(errHandler);
I don't know how to include Tweets when a user is fetched.
You have defined functions, inside your models, that create your associations. However, you never call these functions. After instanciating your Sequelize object and initializing your models, you should run the following code to have your associations created:
for(let modelName in sequelize.models) {
sequelize.models[modelName].associate(sequelize.models);
}
See:
Sequelize models member
Iterating through objects in Javascript

NodeJS Sequelize: Association with alias [alias] does not exist on [model]

i'm using NodeJS & Sequelize for a school project and i'm struggling on making associations w/ sequelize work. I tried a couple of things before but nothing that made my day.
Basically the thing is that a user can have several playlists (hasMany).
And a playlist belongs to a user (belongsTo).
My error is:
Association with alias "playlist" does not exist on users
Here are my models:
/* USER MODEL */
const Sequelize = require('sequelize');
const { db } = require('../utils/db');
const User = db.define('users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
userID: {
type: Sequelize.INTEGER,
allowNull: false,
field: 'user_id',
},
firstName: {
type: Sequelize.STRING,
field: 'first_name',
allowNull: false,
},
}, {
underscored: true,
tableName: 'users',
freezeTableName: true, // Model tableName will be the same as the model name
});
module.exports = {
User,
};
/* PLAYLIST MODEL */
const sequelize = require('sequelize');
const { db } = require('../utils/db');
const Playlist = db.define('playlist', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: sequelize.INTEGER,
},
name: {
type: sequelize.STRING,
field: 'name',
allowNull: false,
},
coverUrl: {
type: sequelize.STRING,
field: 'cover_url',
allowNull: true,
},
ownerId: {
type: sequelize.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'user_id',
},
},
}, {
underscored: true,
tableName: 'playlist',
freezeTableName: true,
});
module.exports = {
Playlist,
};
Here is how i load my models:
const { Credentials } = require('./credentials');
const { User } = require('./users');
const { Playlist } = require('./playlist');
function loadModels() {
User.associate = (models) => {
User.hasMany(models.Playlist, { as: 'playlist' });
};
Playlist.associate = (models) => {
Playlist.belongsTo(models.User, { foreignKey: 'owner_id', as: 'owner' });
};
Credentials.sync({ force: false });
User.sync({ force: false });
Playlist.sync({ force: false });
}
module.exports = {
loadModels,
};
And finally here is my query where i get this error:
const express = require('express');
const { auth } = require('../../middlewares/auth');
const { Playlist } = require('../../models/playlist');
const { User } = require('../../models/users');
const router = express.Router();
router.get('/playlist', [], auth, (req, res) => {
User.findOne({
where: { userID: req.user.user_id }, include: 'playlist',
}).then((r) => {
console.log(r);
});
});
module.exports = router;
I'm trying to get all the playlist that belongs to a user.
I removed all the useless code (jwt check etc..)
So when i'm doing a get request on /playlist I get:
Unhandled rejection Error: Association with alias "playlist" does not exist on users.
I understand the error but don't understand why i get this.
What did I miss, any ideas ?
Thanks,
I finally fixed it by re-make all my models and definitions with migrations.
I had the same problem and the solution was that Sequelize pluralize the models name so in my case "playlist" does not exist on users because Sequelize pluralized my model so I had to put "Playlists" instead.

Resources