Sequelizenot mapping correctly belongs to many - node.js

I have a Categories table, Attributes and an intermediate table, AttributeCategory, which has id, attribute_id, category_id, date and value, the problem is that when sequelize maps the relationship if the attribute_id and category_id match it does not map it correctly, example:
Category table: id = 1, description = "some"
Attribute table: id = 1, description = "one", id = 2, description = "two"
Category Attribute Table,
id = 1, category_id = 1, attribute_id = 1, value = 10, date = 2020-05-10
id = 2, category_id = 1, attribute_id = 1, value = 15, date = 2020-05-15
id = 3, category_id = 1, attribute_id = 2, value = 10, date = 2020-05-10
The query to db does it correctly, but when it maps the object it only returns me:
id = 2, category_id = 1, attribute_id = 1, value = 15, date = 2020-05-15
id = 3, category_id = 1, attribute_id = 2, value = 10, date = 2020-05-10
as the same attribute_id and category_id are repeated, it only returns the last one.
My models are:
// Atrributes
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class InmAtributo 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) {
// Atributo tiene varias categorias
InmAtributo.belongsToMany(models.InmCategoria, {
as: 'categorias',
through: models.InmAtributoCategoria,
foreignKey: 'atributo_id',
otherKey: 'categoria_id'
});
}
};
InmAtributo.init({
descripcion: DataTypes.STRING,
abreviado: DataTypes.STRING
}, {
sequelize,
modelName: 'InmAtributo',
tableName: 'inm_atributos',
timestamps: false,
});
return InmAtributo;
};
//Categorys
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class InmCategoria 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) {
// Categoria tiene varios atributos
InmCategoria.belongsToMany(models.InmAtributo, {
as: 'atributos',
through: models.InmAtributoCategoria,
foreignKey: 'categoria_id',
otherKey: 'atributo_id'
});
}
};
InmCategoria.init({
descripcion: DataTypes.STRING,
abreviado: DataTypes.STRING
}, {
sequelize,
modelName: 'InmCategoria',
tableName: 'inm_categorias',
timestamps: false,
});
return InmCategoria;
};
//AtributoCategoria
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class InmAtributoCategoria 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) {
}
};
InmAtributoCategoria.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
valor: DataTypes.FLOAT,
fecha_activo: DataTypes.DATE,
}, {
sequelize,
modelName: 'InmAtributoCategoria',
tableName: 'inm_atributo_categoria',
timestamps: true,
});
return InmAtributoCategoria;
};
My migrations are:
//Attributes
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('inm_atributos', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
descripcion: {
allowNull: false,
type: Sequelize.STRING(100)
},
abreviado: {
allowNull: false,
type: Sequelize.STRING(5)
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('inm_atributos');
}
};
//Categorys
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('inm_categorias', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
descripcion: {
allowNull: false,
type: Sequelize.STRING(100)
},
abreviado: {
allowNull: false,
type: Sequelize.STRING(5)
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('inm_categorias');
}
};
//AtributoCategoria
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('inm_atributo_categoria', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
atributo_id: {
allowNull: false,
references: {
model: "inm_atributos",
key: "id"
},
type: Sequelize.BIGINT
},
categoria_id: {
allowNull: false,
references: {
model: "inm_categorias",
key: "id"
},
type: Sequelize.BIGINT
},
fecha_activo: {
allowNull: false,
type: Sequelize.DATE
},
valor: {
allowNull: false,
type: Sequelize.FLOAT
},
created_at: {
type: Sequelize.DATE
},
updated_at: {
type: Sequelize.DATE
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('inm_atributo_categoria');
}
};
My function in controller:
async show(req, res) {
try {
const inmCategoria = await InmCategoria.findByPk(req.params.id, {
include: {
association: 'atributos',
through: {
attributes: ['categoria_id', 'atributo_id', 'valor', 'fecha_activo',
'updated_at', 'created_at']
}
}
});
return res.json({ 'status': 'Exito', 'body': inmCategoria })
} catch (error) {
return res.json({ 'status': 'Error', 'body': error.message })
}
},
Result
Query generated automatically
SELECT "InmCategoria"."id", "InmCategoria"."descripcion", "InmCategoria"."abreviado",
"atributos"."id" AS "atributos.id", "atributos"."descripcion" AS "atributos.descripcion",
"atributos"."abreviado" AS "atributos.abreviado", "atributos->InmAtributoCategoria"."id" AS
"atributos.InmAtributoCategoria.id", "atributos->InmAtributoCategoria"."categoria_id" AS
"atributos.InmAtributoCategoria.categoria_id", "atributos->InmAtributoCategoria"."atributo_id"
AS "atributos.InmAtributoCategoria.atributo_id", "atributos->InmAtributoCategoria"."valor" AS
"atributos.InmAtributoCategoria.valor", "atributos->InmAtributoCategoria"."fecha_activo" AS
"atributos.InmAtributoCategoria.fecha_activo", "atributos->InmAtributoCategoria"."updated_at"
AS "atributos.InmAtributoCategoria.updated_at", "atributos->InmAtributoCategoria"."created_at"
AS "atributos.InmAtributoCategoria.created_at" FROM "inm_categorias" AS "InmCategoria" LEFT
OUTER JOIN ( "inm_atributo_categoria" AS "atributos->InmAtributoCategoria" INNER JOIN
"inm_atributos" AS "atributos" ON "atributos"."id" = "atributos-
>InmAtributoCategoria"."atributo_id") ON "InmCategoria"."id" = "atributos-
>InmAtributoCategoria"."categoria_id" WHERE "InmCategoria"."id" = '10';
JSON output
{
"body": {
"id": "10",
"descripcion": "ZONE A01",
"abreviado": "A01",
"atributos": [
{
"id": "10",
"descripcion": "Additional wasteland",
"abreviado": "ABAL",
"InmAtributoCategoria": {
"categoria_id": "10",
"atributo_id": "10",
"valor": 50,
"fecha_activo": "2010-01-01",
"updated_at": "2021-10-06T19:11:27.000Z",
"created_at": "2021-10-06T19:11:27.000Z"
}
},
{
"id": "21",
"descripcion": "Environmental rate",
"abreviado": "TAMIN",
"InmAtributoCategoria": {
"categoria_id": "10",
"atributo_id": "21",
"valor": 120,
"fecha_activo": "2014-01-01",
"updated_at": "2021-10-06T19:11:27.000Z",
"created_at": "2021-10-06T19:11:27.000Z"
}
}
]
}
}
Query result in navicat
id descripcion abreviado atributos.id atributos.descripcion atributos.abreviado atributos.InmAtributoCategoria.id atributos.InmAtributoCategoria.categoria_id atributos.InmAtributoCategoria.atributo_id atributos.InmAtributoCategoria.valor atributos.InmAtributoCategoria.fecha_activo atributos.InmAtributoCategoria.updated_at atributos.InmAtributoCategoria.created_at
|id|descripcion|abreviado|atributos.id|atributos.descripcion|atributos.abreviado|atributos.InmAtributoCategoria.id|atributos.InmAtributoCategoria.categoria_id|atributos.InmAtributoCategoria.atributo_id|atributos.InmAtributoCategoria.valor|atributos.InmAtributoCategoria.fecha_activo|atributos.InmAtributoCategoria.updated_at|atributos.InmAtributoCategoria.created_at|
|10|ZONA A01|A01|10|ADICIONAL BALDIO|ABAL|167|10|10|60|2021-01-01|2021-10-06 16:11:27|2021-10-06 16:11:27|
|10|ZONA A01|A01|21|TASA AMBIENTAL MINIMO|TAMIN|175|10|21|265|2019-01-01|2021-10-06 16:11:27|2021-10-06 16:11:27|
|10|ZONA A01|A01|21|TASA AMBIENTAL MINIMO|TAMIN|179|10|21|800|2021-01-01|2021-10-06 16:11:27|2021-10-06 16:11:27|
Thanks! Cheers!

If you use category_id and attribute_id as foreign keys for the N:M join table then they cannot be the same in two different records because it violates N:M type of relationship between tables.
If you want to store several records with the same pair of values category_id and attribute_id then you need hasMany from InmCategoria to InmAtributoCategoria and belongsTo from InmAtributoCategoria to InmAtributo like this:
class InmCategoria extends Model {
...
static associate(models) {
InmCategoria.hasMany(models.InmAtributoCategoria, {
as: 'atributoCategoria',
foreignKey: 'categoria_id'
});
}
class InmAtributoCategoria extends Model {
...
static associate(models) {
InmAtributoCategoria.belongsTo(models.InmAtributo, {
as: 'atributo',
foreignKey: 'atributo_id'
});
}
And the query will look like this:
const inmCategoria = await InmCategoria.findByPk(req.params.id, {
include: {
association: 'atributoCategoria',
attributes: ['categoria_id', 'atributo_id', 'valor', 'fecha_activo',
'updated_at', 'created_at'],
include: {
association: 'atributo'
}
}
});

Related

Sequelize association table group

I have two tables medforms and category each medform can have multiple categories. for multiple categories, I made another association table medform_categories.
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class MedForm 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
}
};
MedForm.init({
med_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
med_name: {
type: DataTypes.STRING,
allowNull: false
},
}, {
sequelize,
modelName: 'medforms',
});
MedForm.associate = function (models) {
MedForm.hasMany(models.medforms_category, {
foreignKey: 'med_id',
as: 'medform'
});
};
return MedForm;
};
category table schema:
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Category extends Model {
static associate(models) {
}
};
Category.init({
category_id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
category_name: {
type: DataTypes.STRING,
},
}, {
sequelize,
modelName: 'categories',
});
Category.associate = function (models) {
Category.hasMany(models.medforms_category, {
foreignKey: 'category_id',
as: 'category'
});
};
return Category;
};
and finally the association table medform_category
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Medform_categories extends Model {
static associate(models) {
}
};
Medform_categories.init({
medform_category_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
category_id: {
type: DataTypes.INTEGER,
references: {
model: 'categories',
key: 'category_id'
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE'
},
med_id: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: 'medforms',
key: 'med_id'
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE'
},
}, {
sequelize,
modelName: 'medform_categories',
});
Medform_categories.associate = function (models) {
Medform_categories.belongsTo(models.medforms, {
foreignKey: 'med_id',
as: 'medform'
});
Medform_categories.belongsTo(models.categories, {
foreignKey: 'category_id',
as: 'category'
});
};
return Medform_categories;
};
now I want data like:
"category": [
{
"category_id": 1,
"category_name": "cat1",
"medforms": {
"med_id": 1,
"med_name": "Mobilfunk 1",
"med_fullname": "Mobilfunk 1",
},
{
"med_id": 2,
"med_name": "Mobilfunk 2",
"med_fullname": "Mobilfunk 2",
}
},
{
"category_id": 2,
"category_name": "cat2",
"medforms": {
"med_id": 1,
"med_name": "Mobilfunk 1",
"med_fullname": "Mobilfunk 1",
},
{
"med_id": 3,
"med_name": "Mobilfunk 3",
"med_fullname": "Mobilfunk 3",
}
},
]
can some one please help me here? what I should do here? Inside the
controller to fetch data like mentioned above?
const db = require("../models");
const Categories = db.categories; // tables db instance
// Retrieve all objects (with include)
exports.getAllCategories = (req, res) => {
Categories.findAll({
include: [
{
model: db.medforms_category,
as: 'category',
include: [
{
model: db.medforms,
as: 'medform',
}]
},
],
})
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving all data."
});
});
};
If you have a N:N relation, you not necessarely need to have a Model to represent this table.
// Medforms
// ...
static associate(models) {
this.belongsToMany(models.categories, { through: 'medform_categories' });
}
// Categories
// ...
static associate(models) {
this.belongsToMany(models.medforms, { through: 'medform_categories' });
}
// Query will be something like
const categories = await Categories.findAll({
where: {...},
include: ['medforms']
})
const medforms = await Medforms.findAll({
where: {...},
include: ['categories']
})

Sequelize limit breaks the request

my model Complaint:
module.exports = (sequelize, DataTypes) => {
class complaint extends Model {
static associate(models) {
this.research = this.hasMany(models.research, {as: 'research', foreignKey: 'complaint_id' })
}
}
complaint
.init({
date: {
type: DataTypes.DATE,
allowNull: false,
},
complaint: {
type: DataTypes.TEXT,
allowNull: false,
},
}, {
sequelize,
modelName: 'complaint',
freezeTableName: true,
tableName: 'complaint',
})
return complaint
}
my model Research:
module.exports = (sequelize, DataTypes) => {
class research extends Model {
static associate(models) {
this.complaint = this.belongsTo(models.complaint, { foreignKey: 'id'})
}
}
research.init({
complaint_id: {
type: DataTypes.INTEGER,
model: 'complaint',
key: 'id',
deferrable: Deferrable.INITIALLY_IMMEDIATE(),
},
research: {
type: DataTypes.JSONB,
allowNull: false,
},
}, {
sequelize,
modelName: 'research',
freezeTableName: true,
tableName: 'research',
})
return research
}
my query
const query = {
where: {
'$research.id$': null,
},
limit: 3,
attributes: [
'id',
'date',
],
include: [
{
model: models.research,
as: 'research',
attributes: ['id','complaint_id'],
},
],
order: [["date","ASC"]],
}
const complaint = await models.complaint.findAll(query) // <--- error "missing FROM-clause entry for table \"research\""
if remove "limit: 3" it works fine. also with a limit: 3 a strange sql is generated:
without limit:3
SELECT "complaint"."id", "complaint"."date", "research"."id" AS "research.id"
FROM "complaint" AS "complaint"
LEFT OUTER JOIN "research" AS "research" ON "complaint"."id" = "research"."complaint_id"
WHERE "complaint"."sub_id" IS NULL
AND "research"."id" IS NULL
ORDER BY "complaint"."date" ASC;
with limit:3
SELECT "complaint".*, "research"."id" AS "research.id"
FROM (SELECT "complaint"."id", "complaint"."date"
FROM "complaint" AS "complaint"
WHERE "complaint"."sub_id" IS NULL
AND "research"."id" IS NULL
ORDER BY "complaint"."date" ASC
LIMIT 3) AS "complaint"
LEFT OUTER JOIN "research" AS "research" ON "complaint"."id" = "research"."complaint_id"
ORDER BY "complaint"."date" ASC;
although only the word is expected to change from "research"."id" is NULL to "research"."id" notNULL
This is a bug in my request or in the Sequelize code?

Node Sequelize Relational Challenge

I have three tables (all associated model classnames use PascalCase)
schools school_codes course
------ ------ ------
id (pk) code (pk) name
name school_id (fk) school_code (fk)
I'm trying to define sequelize relations, so that this Course lookup returns the associated School:
const courseWithSchool = await models.Course.findOne({
include: [{
model: models.School,
required: true,
}],
})
The mysql for this is very simple.
mysql> select c.*, s.* from courses c inner join school_codes sc on c.school_code = sc.code inner join schools s on s.id = sc.school_id;
How do I define the relations in sequelize models (without modifying existing schema)? Thanks!
Here are the model definitions I have:
schools.js
module.exports = (sequelize, DataTypes) => {
const School = sequelize.define('School', {
name: DataTypes.STRING,
}, { underscored: true, freezeTableName: true, tableName: 'schools' })
return School
}
course.js
module.exports = (sequelize, DataTypes) => {
const Course = sequelize.define('Course', {
id: {
type: DataTypes.STRING,
primaryKey: true,
},
name: DataTypes.STRING,
school_code: {
type: DataTypes.STRING,
references: {
model: 'school_codes',
key: 'code',
}
}
}, { underscored: true, freezeTableName: true, tableName: 'courses' })
return Course
}
schoolcode.js
module.exports = (sequelize, DataTypes) => {
const SchoolCode = sequelize.define('SchoolCode', {
code:{
type: DataTypes.STRING,
primaryKey: true,
references: {
model: 'courses',
key: 'school_code'
}
},
school_id: {
type: DataTypes.INTEGER,
references: {
model: 'schools',
key: 'id',
},
},
}, { underscored: true, freezeTableName: true, tableName: 'school_codes', })
return SchoolCode
}
I'm just looking for the relations to add to the bottom of each model definition - example...
// School.associate = function (models) {
// School.belongsToMany(models.Course, {
// through: 'school_codes',
// foreignKey: 'school_id',
// otherKey: 'code'
// })
// }
We can keep association in its respective model. I prefer to keep association in respective master table rather than mapping table. The idea is to associate source model to target model and its relationship in both direction. For example let us say source model School has one SchoolCode target model and its reverse relation
//school.model.js
module.exports = (sequelize, DataTypes) => {
const School = sequelize.define('school', {
name: DataTypes.STRING,
}, { underscored: true, freezeTableName: true, tableName: 'schools' })
School.associate = function ({SchoolCode, Course}) {
School.hasOne(SchoolCode, {
foreignKey: 'school_id',
})
SchoolCode.belongsTo(School, {foreignKey: 'school_id'})
School.belongsToMany(Course, { through: SchoolCode , foreignKey : 'school_id'}); //added new
}
return School;
}
//course.model.js
module.exports = (sequelize, DataTypes) => {
const Course = sequelize.define('course', {
id: {
type: DataTypes.STRING,
primaryKey: true,
},
name: DataTypes.STRING,
school_code: {
type: DataTypes.STRING,
references: {
model: 'school_codes',
key: 'code',
}
}
}, { underscored: true, freezeTableName: true, tableName: 'courses' })
Course.associate = function ({SchoolCode, School}) {
Course.hasMany(SchoolCode, {
foreignKey: 'code',
})
Course.belongsToMany(School, { through: SchoolCode, foreignKey : 'code'}); //added new
}
return Course;
}
Finally the third model of SchoolCode (Mapping table).
Note that we don't have to add a reference school_code. It is a primaryKey code of same table. We use references mainly to define the foreign keys, no need for reverse definition here.
Hence commented that part from code below.
module.exports = (sequelize, DataTypes) => {
const SchoolCode = sequelize.define('SchoolCode', {
code:{
type: DataTypes.STRING,
primaryKey: true,
// references: {
// model: 'courses',
// key: 'school_code'
// }
},
school_id: {
type: DataTypes.INTEGER,
references: {
model: 'school',
key: 'id',
},
},
}, { underscored: true, freezeTableName: true, tableName: 'school_codes', })
return SchoolCode
}
References : https://sequelize.org/master/manual/assocs.html
You can define relations like
SchoolCode.belongsTo(School, { foreignKey: 'school_id', targetKey: 'id' });
Course.belongsTo(SchoolCode, { foreignKey: 'school_code', targetKey: 'code' });

Node Sequelize inserting wrong field position on many to many table

I have a many to many relationship between the tables DeliveryOrder and GasBottle with the extra field Amount, but when i try to insert some values in this table, sequelize change´s the field order.
My models:
const {Model,DataTypes} = require ('sequelize')
class GasBottle extends Model{
static init(sequelize){
super.init({
type: DataTypes.INTEGER,
costPrice: DataTypes.DOUBLE,
sellPrice: DataTypes.DOUBLE
},{sequelize})
}
static associate({ DeliveryOrder,DeliveryOrderGasBottle}) {
GasBottle.belongsToMany(DeliveryOrder, {
through: DeliveryOrderGasBottle,
as: "deliveryOrders",
foreignKey: "deliveryOrderId",
});
}
}
module.exports = GasBottle
const { Model, DataTypes } = require("sequelize");
class DeliveryOrder extends Model {
static init(sequelize) {
super.init(
{
status: DataTypes.INTEGER,
latitude: DataTypes.INTEGER,
longitude: DataTypes.INTEGER,
delivererId: {
type: DataTypes.INTEGER,
references: {
model: "Deliverer",
key: "id",
},
},
},
{ sequelize }
);
}
static associate({ Deliverer, GasBottle, DeliveryOrderGasBottle }) {
DeliveryOrder.belongsTo(Deliverer, { foreignKey: "delivererId" });
DeliveryOrder.belongsToMany(GasBottle, {
through: DeliveryOrderGasBottle,
as: "bottles",
foreignKey: "gasBottleId",
});
}
}
module.exports = DeliveryOrder;
const { Model, DataTypes } = require("sequelize");
class DeliveryOrderGasBottle extends Model {
static init(sequelize) {
super.init(
{
gasBottleId: {
type: DataTypes.INTEGER,
references: {
model: "GasBottle",
key: "id",
},
},
deliveryOrderId: {
type: DataTypes.INTEGER,
references: {
model: "DeliveryOrder",
key: "id",
},
},
amount: DataTypes.INTEGER,
},
{ sequelize }
);
}
}
module.exports = DeliveryOrderGasBottle;
My migration file:
"use strict";
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable("DeliveryOrderGasBottle", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
gasBottleId: {
type: Sequelize.INTEGER,
references: {
model: "GasBottle",
key: "id",
},
allowNull: false,
onDelete: "CASCADE",
},
deliveryOrderId: {
type: Sequelize.INTEGER,
references: {
model: "DeliveryOrder",
key: "id",
},
allowNull: false,
onDelete: "CASCADE",
},
amount:{
type: Sequelize.DOUBLE,
allowNull: false,
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable("DeliveryOrderGasBottle");
},
};
My association:
const deliveryOrder = await DeliveryOrder.create(obj);
bottlesToAdd.map(async (bottle) => {
const db_bottle = await GasBottle.findByPk(bottle.id);
await deliveryOrder.addBottle(db_bottle, {
through: { amount: parseInt(bottle.amount) },
});
On insert, sequelize is changing the order of the ids, resulting in a constraint error because i dont have the id´s on the respective tables
INSERT INTO "DeliveryOrderGasBottle" ("gasBottleId","deliveryOrderId","amount","createdAt","updatedAt") VALUES (18,1,42,'2020-06-27 19:17:26.204 +00:00','2020-06-27 19:17:26.204 +00:00')

Update with association using Sequelize.js

I am trying to update with association using sequelize.js.
I have tried give example on stackoverflow namely the following links:
Sequelize update with association
Sequelize update with association
Updating attributes in associated models using Sequelize
all of these links did not get me to the goal i am trying to accomplish.
My model is as follow, I have a country module and a city module. a country has many cities. please refer to the module bellow.
Please advise.
country.js file
module.exports = function (sequelize, DataTypes) {
var country= sequelize.define('COUNTRY', {
COUNTRY_ID: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
COUNTRY_NAME: DataTypes.STRING,
COUNTRY_CURRENCY: DataTypes.STRING
}, {
freezeTableName: true,
classMethods: {
associate: function (models) {
COUNTRY_ID.hasMany(models.CITIES, {
foreignKey: 'COUNTRY_ID'
})
}
},
instanceMethods: {
updateAssociation: function (onSuccess, onError) {
country.findAll({
where: {
COUNTRY_ID: req.params.country_id
},
include: [
{
model: sequelize.import('./cities.js'),
}
]
})
})
.then(country =>{
const updatePromises = country.map(countries =>{
return countries.updateAttributes(req.body);
});
const updatePromisescities = list.CITY.map(cities =>{
return cities.updateAttributes(req.body.CITYs[0]);
});
return sequelize.Promise.all([updatePromises, updatePromisescities ])
}).then(onSuccess).error(onError);
}
}
});
return country;
};
city.js file
module.exports = function (sequelize, DataTypes) {
var CITY = sequelize.define('LIST_CODE', {
CITY_ID: {
type: DataTypes.INTEGER,
primaryKey: true
},
COUNTRY_ID: {
type: DataTypes.INTEGER,
primaryKey: true
}
}, {
freezeTableName: true,
timestamps: false,
classMethods: {
associate: function (models) {
// associations can be defined here
CITY.belongsTo(models.COUNTRY, {
foreignKey: 'COUNTRY_ID'
})
}
}
});
return CITY;
};

Resources