How clear many to many relation table on delete entity - node.js

How make autoclear relation table when one of entity deleted ? Now when I delete task or type in relation table tasks_types_realations still exist record with id of deleted entity, for example I have task with id: 1, and type with id: 1, in relation table it will |taskId:1|typeId:1|, and after delete task or type record still exist.
Task model:
module.exports = (sequelize, DataTypes) => {
const Task = sequelize.define('task', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
status: {
type: DataTypes.ENUM,
values: ['done', 'pending', 'cancel'],
defaultValue: 'pending',
allowNull: false
},
date: {
type: DataTypes.DATE,
allowNull: false
},
})
Task.associate = models => {
Task.TaskType = Task.belongsToMany(models.TaskType, {
as: 'types',
through: models.TasksTypes
})
}
return Task
}
Type model:
module.exports = (sequelize, DataTypes) => {
const TaskType = sequelize.define(
'taskType',
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
unique: true
}
},
{
tableName: 'tasks_types'
}
)
TaskType.associate = models => {
TaskType.Task = TaskType.belongsToMany(models.Task, {
as: 'tasks',
foreignKey: 'typeId',
through: models.TasksTypes
})
}
return TaskType
}

In task model add:
Task.TasksTypes = Task.hasMany(models.TasksTypes, {
as: 'typesRelations',
foreignKey: 'taskId',
hooks: true,
onDelete: 'cascade'
})
In type model add:
TaskType.TasksTypes = TaskType.hasMany(models.TasksTypes, {
as: 'tasksRelations',
foreignKey: 'typeId',
hooks: true,
onDelete: 'cascade'
})

Related

postgres returns another table column while inserting data in sequelize

When I try to insert new category, I got this error:
error: column "image" does not exist
sql: 'INSERT INTO "Categories" ("id","createdAt","updatedAt") VALUES (DEFAULT,$1,$2) RETURNING "id","image","title","createdAt","updatedAt";'
The problem is that it doesn't insert name and other values and returns columns belong to post table.
My guesses are the problem of sequelize-cli and sequelize version or missing something in models or migrations.
I only insert values into name, createdAt and updatedAt column:
await Category.create({
name: req.body.name,
createdAt: new Date(),
updatedAt: new Date()
});
My category model:
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class Category extends Model {
static associate(models) {
Category.hasMany(models.Post, { as: "posts", foreignKey: "categoryId" });
}
}
Category.init(
{
name: DataTypes.STRING
},
{
sequelize,
modelName: "Category"
}
);
return Category;
};
My Post Model:
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class Post extends Model {
static associate(models) {
Post.belongsTo(models.Category, { foreignKey: "categoryId", onDelete: "CASCADE", as: "category" });
}
}
Post.init(
{
title: DataTypes.STRING,
image: DataTypes.STRING,
content: DataTypes.TEXT,
categoryId: DataTypes.INTEGER
},
{
sequelize,
modelName: "Post"
}
);
return Post;
};
Post migration:
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable("Posts", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING
},
image: {
type: Sequelize.STRING
},
content: {
type: Sequelize.TEXT
},
categoryId: {
type: Sequelize.INTEGER,
allowNull: false,
onDelete: "CASCADE",
references: {
model: "Categories",
key: "id"
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
Category migration:
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable("Categories", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
I couldn't find solution for this, therefor I used sequelize.query

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'

Sequelize findAndCountAll and count included model

I use postgresql/sequelize and findAndCountAll function.
Entry.findAndCountAll({
where: {TitleId: title.id},
include: [
{model: User, as: 'users', attributes: ['username']},
{model: EntryHasLike} // I need to count this. model.
],
offset: 15 * (req.body.page - 1),
limit: 15
}).then(entries => {
res.json({
title: title,
count: entries.count,
entries: entries.rows // [I want to count of likes inside this table]
})
}).catch(err => {}
I'm counting entries with findAndCountAll but I want additionally count of EntryHasLikes model which is the same with Entries.Id.
EntryHasLike model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const EntryHasLike = sequelize.define('EntryHasLike', {
EntryId: {
type:DataTypes.INTEGER,
allowNull: false,
primaryKey: true
},
UserId: {
type:DataTypes.INTEGER,
allowNull: false
},
likeDate: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
}
},{
timestamps: false
});
EntryHasLike.associate = function(models) {
EntryHasLike.belongsTo(models.User)
EntryHasLike.belongsTo(models.Entry)
};
return EntryHasLike;
};
Entry model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const Entry = sequelize.define('Entry', {
UserId: {
type: DataTypes.INTEGER,
allowNull: false
},
entry: {
type: DataTypes.TEXT,
allowNull: false
},
entryRev: {
type: DataTypes.STRING,
defaultValue: 1
},
entryRefId: {
type: DataTypes.INTEGER,
defaultValue: null
},
entryCondition: {
type: DataTypes.INTEGER,
defaultValue: 1
},
activity: {
type: DataTypes.INTEGER,
defaultValue: 1
},
TitleId: {
type: DataTypes.INTEGER,
allowNull: false
}
}, {});
Entry.associate = function(models) {
Entry.belongsTo(models.Title, {foreignKey: 'TitleId', as: 'titles'})
Entry.belongsTo(models.User, {foreignKey: 'UserId', as: 'users'})
Entry.belongsToMany(models.EntryCat, {through: 'EntryHasCats', as: 'entrycats'})
Entry.belongsToMany(models.EntryTag, {through: 'EntryHasTags', as: 'entrytags'})
Entry.hasMany(models.EntryHasLike)
};
return Entry;
};
I tried many solutions but i couldn't get result. As you see related questions in below but all of about findAll function. My function is findAndCountAll
Counting associated entries with Sequelize
Sequelize 'hasMany' associated(model) count in attributes in query execution
Maybe on client you can take length of Entry.EntryHasLike
setEntry(data) {
this._entry = {
...data,
count: data.EntryHasLike.length
}
}

sequelize count does not work with nested objects

pInvent.js
module.exports = (sequelize, DataTypes) => {
const PInvent = sequelize.define('prod_invent', {
id: {primaryKey: true, type: DataTypes.INTEGER, autoIncrement: true, allowNull: false, unique: true},
sku_id: {
type: DataTypes.STRING,
allowNull: false,
unique: true
}
});
PInvent.associations = (db) => {
PInvent.belongsToMany(db.cTags, {
as: 'CTags',
through: 'c_prod',
foreignKey: 'prod_id',
otherKey: 'c_id'
});
};
return PInvent
}
pCure.js
module.exports = (sequelize, DataTypes) => {
const PCure = sequelize.define('prod_cure', {
id: {primaryKey: true, type: DataTypes.INTEGER, autoIncrement: true, allowNull: false, unique: true},
c_tag: {type: DataTypes.STRING, allowNull: false, unique: true}
});
PCure.associations = (db) => {
PCure.belongsToMany(db.pInvent, {
as: 'CProd',
through: 'c_prod',
foreignKey: 'c_id',
otherKey: 'prod_id'
});
};
return PCure
}
db.js
db.pInvent = require('../model/pInvent')(sequelize, Sequelize);
db.cTags = require('../model/pCure')(sequelize, Sequelize);
db.cTags.associations(db);
Now when I write the code as shown below :
db.cTags.findAll({
attributes: ['prod_cure.*', 'prod_invent.*', [Sequelize.fn('COUNT', Sequelize.col('prod_invent.id')), 'PostCount']],
include: [{
model: db.pInvent, as: 'CProd'
}]
}).then((data) => {
res.json({info:data})
}).catch((err) => {
res.json({errInfo:err})
})
it gives me the error as shown below :
Unknown table 'prod_invent'
What i want here is , i wanted calculate the count of nested object , but i am not able to do.

findall many to many sequelize

I have a list of many to many of the people tables and lists. I need to make a query that includes the relation table, something like:
SELECT p.id, pl.id
FROM people p inner join peopletolists pl
WHERE p.id == pl.id
My models:
Lists model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const lists = sequelize.define('lists', {
listId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
nome: DataTypes.STRING(50),
status: DataTypes.STRING(1),
parametros: DataTypes.STRING(500)
}, {
timestamps: false,
});
lists.associate = function(models) {
lists.belongsToMany(models.people, {
through: models.peopletolists,
foreignKey: 'listId',
});
}
return lists;
};
People model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const people = sequelize.define('people', {
peopleId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
cpf: DataTypes.STRING(11),
name: DataTypes.STRING(50),
city: DataTypes.STRING(50),
}, {
timestamps: false
});
people.associate = function (models) {
people.belongsToMany(models.lists, {
through: models.peopletolists,
foreignKey: 'peopleId'
});
}
return people;
};
N:M model:
'use strict';
module.exports = function (sequelize, DataTypes) {
const peopletolists = sequelize.define("peopletolists", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true,
},
listId: {
type: DataTypes.INTEGER,
references: {
model: 'lists',
key: 'listId'
},
allowNull: false
},
peopleId: {
type: DataTypes.INTEGER,
references: {
model: 'people',
key: 'peopleId'
},
allowNull: false
}
}, {
timestamps: false
});
return peopletolists;
}
Query:
router.get('/', function (req, res, next) {
model.lists.findAll({
include: [{
model: model.peopletolists,
}]
})
.then(lists => res.json({
data: lists,
}))
.catch(err => res.json({
error: err,
}))
});
Error: SequelizeEagerLoadingError
A person has many lists and lists have many people. I have not found many things in the Sequelize documentation and not many people complaining about this error, it's generally on ClassMethods, but I'm not even using it.
What's wrong?
This is how I am using it.
ArtistModel.findAll({
where: {
slug: req.params.slug
}, attributes: ['id']
, include: [{
model: Genres,
as: 'ArtistGenre',
required: false,
// attributes: ['id'],
through: {attributes: []},
}],
subQuery: false,
limit: req.query.limit,
offset: req.skip
})
Where Genre is the table that is linked with the Artist table with a many-to-many relationship through ArtistGenre
ArtistGenre Model:
const db = require('../utils/connection');
const Sequelize = require('sequelize');
let ArtistGenre = db.define('artist_genre', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
}
}, {
timestamps: false,
underscored: true
});
ArtistGenre.removeAttribute('id');
module.exports = ArtistGenre;
Artist:
const db = require('../utils/connection');
const Sequelize = require('sequelize');
module.exports = db.define('artist', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING
},
status: {
type: Sequelize.ENUM,
values: ['active', 'inactive'],
defaultValue: 'active'
},
created_at: {
type: 'TIMESTAMP',
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false
},
updated_at: {
type: 'TIMESTAMP',
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false
}
}, {
underscored: true,
timestamps: false
});
Genre Model:
const db = require('../utils/connection');
const Sequelize = require('sequelize');
module.exports = db.define('genre', {
id: {
type: Sequelize.BIGINT(20),
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING
}
}, {
timestamps: false
});
Associations are like the following:
Artist.belongsToMany(models.genre, {as: 'ArtistGenre', through: 'artist_genre', foreignKey: 'artist_id', otherKey: 'genre_id'});
Genre.belongsToMany(models.artist, {as: 'ArtistGenre', through: 'artist_genre', foreignKey: 'genre_id', otherKey: 'artist_id'});

Resources