SequelizeForeignKeyConstraintError - mysql

I'm having problems with associations using Sequelize. I'm trying to create a Task, and it should belong to a User and a Department.
Here is my Task file:
module.exports = function (sequelize, DataTypes) {
var Task = sequelize.define("Task", {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
task_name: {
type: DataTypes.STRING,
notNull: true
},
description: {
type: DataTypes.STRING,
notNull: true
},
completed: {
type: DataTypes.BOOLEAN
}
}, {
tableName: 'tasks',
timestamps: false,
});
Task.associate = function (models) {
Task.belongsTo(models.Department, {
onDelete: 'CASCADE',
allowNull: true
});
Task.belongsTo(models.User, {
onDelete: 'CASCADE',
allowNull: true
});
}
return Task;
};
My departments file:
module.exports = function (sequelize, DataTypes) {
var Department = sequelize.define("Department", {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
departmentName: DataTypes.STRING,
description: {
type: DataTypes.STRING,
notNull: true
}
}, {
tableName: 'departments',
timestamps: false,
});
Department.associate = function (models) {
Department.belongsTo(models.Project, {
allowNull: true
});
Department.hasMany(models.Task, {
allowNull: true
});
}
return Department;
};
And finally my User file:
const bcrypt = require('bcryptjs');
module.exports = function (sequelize, Sequelize) {
var User = sequelize.define('User', {
id: {
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
fullname: {
type: Sequelize.STRING,
notEmpty: true
},
username: {
type: Sequelize.TEXT
},
email: {
type: Sequelize.STRING,
validate: {
isEmail: true
}
},
password: {
type: Sequelize.STRING,
allowNull: false
},
last_login: {
type: Sequelize.STRING
}
}, {
tableName: 'users',
timestamps: false
});
User.associate = function (models) {
User.hasMany(models.Task, {});
}
User.prototype.validPassword = function (password) {
return bcrypt.compareSync(password, this.password);
};
User.hook("beforeCreate", (instance) => {
if (instance.password) {
instance.password = bcrypt.hashSync(instance.password, bcrypt.genSaltSync(10), null);
}
});
return User;
}
I have googled high and low for an answer to this and I cannot find anything! Help is much appreciated.

Related

Creating Associations with sequelize and mysql

I am trying to create seqeulize models in nodejs app on mysql db. However, When I run the codes, foreign keys are not being created as intended.
This are my models:
Category Model
"use strict";
module.exports = (sequelize, DataTypes) => {
const Category = sequelize.define("Category", {
category_id: {
type: DataTypes.STRING(255),
unique: true,
primaryKey: true,
},
name: { type: DataTypes.STRING, unique: true, allowNull: false },
slug: { type: DataTypes.STRING, unique: true, allowNull: false },
created_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal("CURRENT_TIMESTAMP"),
},
updated_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
),
},
});
Category.associate = (models) => {
Category.hasMany(models.Product);
};
return Category;
};
Product Model
"use strict";
module.exports = (sequelize, DataTypes) => {
const Product = sequelize.define("Product", {
product_id: {
type: DataTypes.STRING(255),
allowNull: false,
unique: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
slug: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
sku: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
short_description: {
type: DataTypes.TEXT,
allowNull: false,
},
description: {
type: DataTypes.TEXT,
allowNull: false,
},
price: {
type: DataTypes.DECIMAL,
allowNull: false,
min: 1,
},
discount: {
type: DataTypes.DECIMAL,
allowNull: true,
},
quantity: {
type: DataTypes.INTEGER,
},
vat: {
type: DataTypes.DECIMAL,
allowNull: true,
},
tags: {
type: DataTypes.STRING(255),
allowNull: true,
},
rate: {
type: DataTypes.INTEGER,
allowNull: true,
},
points: {
type: DataTypes.INTEGER,
allowNull: true,
},
new: {
type: DataTypes.VIRTUAL,
get() {
var msPerDay = 8.64e7;
// Copy dates so don't mess them up
var x0 = new Date(this.getDataValue("created_at"));
var x1 = new Date();
// Set to noon - avoid DST errors
x0.setHours(12, 0, 0);
x1.setHours(12, 0, 0);
// Round to remove daylight saving errors
return Math.round((x1 - x0) / msPerDay) <= 30;
},
set(value) {
throw new Error("Can't set Product.new property.");
},
},
thumb_image: {
type: DataTypes.STRING,
allowNull: true,
get() {
if (this.getDataValue("thumb_image")) {
return JSON.parse(this.getDataValue("thumb_image"));
}
return [];
},
set(val) {
this.setDataValue("thumbImage", JSON.stringify(val));
},
},
images: {
type: DataTypes.STRING,
allowNull: true,
get() {
if (this.getDataValue("images")) {
return JSON.parse(this.getDataValue("images"));
}
return [];
},
set(val) {
this.setDataValue("images", JSON.stringify(val));
},
},
featured: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
created_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal("CURRENT_TIMESTAMP"),
},
updated_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
),
},
});
Product.associate = (models) => {
Product.belongsTo(models.Category, {
foreignKey: "category_id",
});
Product.belongsTo(models.Brand, {
foreignKey: "brand_id",
});
Product.belongsTo(models.CartItem, {
foreignKey: "cart_id",
});
};
return Product;
};
Brand Model
"use strict";
module.exports = (sequelize, DataTypes) => {
const Brand = sequelize.define("Brand", {
brand_id: {
type: DataTypes.STRING(255),
unique: true,
primaryKey: true,
},
name: { type: DataTypes.STRING, unique: true, allowNull: false },
slug: { type: DataTypes.STRING, unique: true, allowNull: false },
created_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal("CURRENT_TIMESTAMP"),
},
updated_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
),
},
});
Brand.associate = (models) => {
Brand.hasMany(models.Product);
};
return Brand;
};
And these is my Models/index.js file
/* eslint-disable no-undef */
"use strict";
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || "development";
const config = require(__dirname + "/../../config/config.js")[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(
config.database,
config.username,
config.password,
config
);
}
db.sequelize = sequelize;
db.Sequelize = Sequelize;
fs.readdirSync(__dirname)
.filter((file) => {
return (
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
);
})
.forEach((file) => {
const model = require(path.join(__dirname, file))(
sequelize,
Sequelize.DataTypes
);
db[model.name] = model;
});
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize
.sync({ force: process.env.NODE_ENV === "development" })
.then(() => {
console.log("Drop and re-sync db.");
});
module.exports = db;
Now when I run the server, I expected the products table to have the fields category_id and brand_id. However, am getting additional fields brand_brand_id and category_category_id on the products table.
Besides, I cannot retrieve the categories, brands and products with the include properties when fecthing data.
What I want is to have the products table properly created in the database with the required foreign keys
Since you have customized foreign keys you have to indicate them in both paired associations:
Category.associate = (models) => {
Category.hasMany(models.Product, { foreignKey: "category_id" });
};
Product.associate = (models) => {
Product.belongsTo(models.Category, {
foreignKey: "category_id",
});
Product.belongsTo(models.Brand, {
foreignKey: "brand_id",
});
Product.belongsTo(models.CartItem, {
foreignKey: "cart_id",
});
};
Brand.associate = (models) => {
Brand.hasMany(models.Product, { foreignKey: "brand_id" });
};

SequelizeEagerLoadingError: product is not associated to collection

I use sequelize ORM in Mysql. I have 3 Models: Product, Collection, CollectionProduct
relationship between Product and Collection are many to many and for handle this in sequelize i used belongsToMany association. every thing is Ok but when i run this code to get a collection with its products with include Eager this error occure:
SequelizeEagerLoadingError: product is not associated to collection!
Product Model:
module.exports = (sequelize, Sequelize) => {
const Product = sequelize.define('product', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
name_en: {
type: Sequelize.STRING(255),
},
description_en: {
type: Sequelize.STRING(1024),
},
price: {
type: Sequelize.FLOAT,
allowNull: false,
},
type: {
type: Sequelize.STRING(255),
},
height: {
type: Sequelize.INTEGER,
},
width: {
type: Sequelize.INTEGER,
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
allowNull: false,
},
}, {})
Product.associate = (models) => {
Product.belongsToMany(models.collection, { through: models.collectionProduct, as: 'collections', foreignKey: 'productId' })
}
return Product
}
Collection Model :
module.exports = (sequelize, Sequelize) => {
const Collection = sequelize.define(
'collection', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
},
name_en: {
type: Sequelize.STRING(255),
},
itemsCount: {
type: Sequelize.INTEGER,
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
allowNull: false,
},
}, {},
)
Collection.associate = (models) => {
Collection.belongsToMany(models.product, { through: models.collectionProduct, as: 'products', foreignKey: 'collectionId' })
}
return Collection
}
CollectionProduct Model:
module.exports = (sequelize, Sequelize) => {
const CollectionProduct = sequelize.define('collectionProduct', {
collectionId: {
type: Sequelize.INTEGER,
},
productId: {
type: Sequelize.INTEGER,
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
allowNull: false,
},
}, {})
CollectionProduct.associate = (models) => {}
return CollectionProduct
}
routes/collection.js
const express = require('express')
const router = express.Router()
const Collection = require('../../controllers/collectionController')
router.get('/:id', async (req, res) => {
const { id: collectionId } = req.params
const collection = await Collection.getOne(collectionId)
return collection
}
collectionController
const db = require('../models/index')
const Collection = db.collection
const Product = db.product
const getOne = async (collectionId) => {
const collection = await Collection.findByPk(collectionId, {
include: {
model: Product,
as: 'products',
attributes: ['id', 'name_en'],
},
})
return collection
}
I found my problem. in collectionController i used model: Product
and Product should be a sequelize model. but in my code this is a function that have been called in models/index. so i changed my calling and pass a sequelize model to getOne

Sequelize: Unable to set reference to two different tables after migrations

I am trying to set reference from donorslist table to user table and requestblood table. Though the references columns(userid, requestbloodid) are getting added to the table, it is failing to insert the reference id 'requestbloodid' in the column and sets it to NULL.
I am using
Nodejs
mysql: 2.16.0 v
sequelize: 4.37.10 v
user.js model file:
const moment = require('moment');
module.exports = (sequelize, DataTypes) => {
const user = sequelize.define(
'user',
{
id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
fullname: {
type: DataTypes.STRING(20),
allowNull: false,
},
gender: { type: DataTypes.CHAR(1), allowNull: false },
latitude: {
type: DataTypes.DECIMAL(20, 15),
allowNull: false,
validate: { min: -90, max: 90 },
},
longitude: {
type: DataTypes.DECIMAL(20, 15),
allowNull: false,
validate: { min: -180, max: 180 },
},
email: {
type: DataTypes.STRING(50),
allowNull: true,
},
isglobalcontactshared: { type: DataTypes.BOOLEAN, defaultValue: false },
createdAt: {
type: DataTypes.DATE,
get() {
return moment.utc(new Date(), 'DD-MMM-YYYY h:mm a').format('DD-MMM-YYYY h:mm a');
},
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: null,
},
},
{
freezeTableName: true,
}
);
user.associate = function(models) {
user.belongsTo(models.contactdetails, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: {
name: 'contactdetailid',
allowNull: false,
foreignKeyConstraint: true,
},
});
};
return user;
};
requestblood.js file:
const moment = require('moment');
module.exports = (sequelize, DataTypes) => {
const requestblood = sequelize.define(
'requestblood',
{
id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
requestid: {
type: DataTypes.STRING(10),
allowNull: false,
},
latitude: {
type: DataTypes.DECIMAL(20, 15),
allowNull: false,
validate: { min: -90, max: 90 },
},
longitude: {
type: DataTypes.DECIMAL(20, 15),
allowNull: false,
validate: { min: -180, max: 180 },
},
locality: { type: DataTypes.STRING(20), allowNull: false },
city: { type: DataTypes.STRING, allowNull: false },
bloodtype: {
type: DataTypes.INTEGER,
allowNull: false,
isNumeric: true,
validate: { min: 1, max: 9 },
},
duedate: {
type: DataTypes.DATEONLY,
allowNull: false,
get() {
return moment.utc(this.getDataValue('duedate')).format('DD-MMM-YYYY');
},
},
unitsrequired: { type: DataTypes.INTEGER, isNumeric: true },
description: { type: DataTypes.STRING(500) },
requeststateid: { type: DataTypes.STRING, allowNull: false },
createdAt: {
type: DataTypes.DATE,
get() {
return moment.utc(new Date(), 'DD-MMM-YYYY h:mm a').format('DD-MMM-YYYY h:mm a');
},
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: null,
},
},
{
freezeTableName: true,
}
);
requestblood.associate = function(models) {
requestblood.belongsTo(models.contactdetails, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: {
name: 'contactdetailid',
allowNull: false,
foreignKeyConstraint: true,
},
});
};
/* requestblood.associate = function(models) {
requestblood.hasMany(models.donorslist, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: {
name: 'requestbloodid',
allowNull: false,
foreignKeyConstraint: true,
},
});
}; */
return requestblood;
};
donorslist.js file
const moment = require('moment');
module.exports = (sequelize, DataTypes) => {
const donorslist = sequelize.define(
'donorslist',
{
id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
fullname: {
type: DataTypes.STRING(20),
allowNull: false,
},
bloodgroup: { type: DataTypes.INTEGER, allowNull: false },
contactnumber: { type: DataTypes.STRING(13), allowNull: true },
willdonate: { type: DataTypes.BOOLEAN, defaultValue: false },
hasdonated: { type: DataTypes.BOOLEAN, defaultValue: false },
createdAt: {
type: DataTypes.DATE,
get() {
return moment.utc(new Date(), 'DD-MMM-YYYY h:mm a').format('DD-MMM-YYYY h:mm a');
},
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: null,
},
},
{
freezeTableName: true,
}
);
donorslist.associate = function(models) {
donorslist.belongsTo(models.requestblood, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: {
name: 'requestbloodid',
allowNull: false,
foreignKeyConstraint: true,
},
});
};
donorslist.associate = function(models) {
donorslist.belongsTo(models.user, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: {
name: 'userid',
allowNull: false,
foreignKeyConstraint: true,
},
});
};
return donorslist;
};
When the below code is executed,
models.donorslist
.create({
fullname,
bloodgroup: bloodgrp,
contactnumber: contnum,
willdonate: req.body.willdonate,
userid: usrid,
requestbloodid: reqid,
updatedAt: null,
})
`
it returns the query as:
INSERT INTO `donorslist` (`id`,`fullname`,`bloodgroup`,`contactnumber`,`willdonate`,`hasdonated`,`createdAt`,`updatedAt`,`userid`) VALUES ('687888be-4381-460f-af62-46365a16fb40','sunil',4,'+123456789',true,false,'2019-01-10 07:00:12','2019-01-10 07:00:12','b93cfd73-a6ea-4825-91ad-8ded37418ca7');
Note the missing requestbloodid column. It somehow skips the requestbloodid column. I am facing this issue, after performing migrations. This was working fine with sequelize.sync(). If i uncomment the below code in requestblood.js file, then the referenceid 'contactdetailid' of requestblood table is set as NULL. So, i am unable to make a reference of belongsTo and hasMany from these two tables.
requestblood.associate = function(models) {
requestblood.hasMany(models.donorslist, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: {
name: 'requestbloodid',
allowNull: false,
foreignKeyConstraint: true,
},
});
};

Sequelize belongsToMany not working

Here is my problem:
Table WO -> sparepart_request -> sparepart.
A work order have several sparepart and sparepart can belong to several WO.
This is my code in wo.js (sequelize model)
models.sparepart.belongsToMany(models.wo, { as: 'SPWO', through: 'sparepart_request', foreignKey: 'codSparePart' });
This is my code in sparepart.js (sequelize model).
models.sparepart.belongsToMany(models.wo, { as: 'SPWO', through: 'sparepart_request', foreignKey: 'codSparePart' });
In sparepart_request there is nothing about associations. I've followed the next instructions Sequelize
In my query I have the next code:
exports.readDetailWO = function (req, res) {
models.wo.findAll({
attributes: ['codWO'], // attributes: ['id', 'codWO', 'codSparePart', 'quantity', 'date_request', 'date_reception', 'details', 'codUser', 'received'],
raw: true,
where: {
codWO: req.params.codWO
},
include: [{
model: models.sparepart,
attributes: ['codSparePart', 'name', 'description', 'codManufacturer', 'image_uri', 'stock'],
paranoid: false,
required: false,
as: 'SPWO'
}]
}).then(sparePart => {
if (!sparePart) {
res.status(404);
res.send({
success: false,
message: 'Spare Part not found. ' + req.params.codWO,
data: sparePart
});
} else if (sparePart) {
res.json({
success: true,
message: 'Spare Part found.',
data: sparePart
});
}
}).catch(function (error) {
logger.error(JSON.stringify(error));
res.json({
message: 'Query not successful and error has occured reading',
error: error,
stackError: error.stack
});
return res.status(500);
});
};
But the server's response (using PostMan) is the following:
{
"message": "Query not successful and error has occured reading",
"error": {
"name": "SequelizeEagerLoadingError"
},
"stackError": "SequelizeEagerLoadingError: sparepart is not associated to wo!\n
AS I have been able to read here that maybe the problem that is my primaryKeys are not name id, but now I can change these names...
Where is the problem? Thanks in advance for your help.
Model sparepart_request.js
module.exports = function (sequelize, DataTypes) {
var sparepart_request = sequelize.define('sparepart_request', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
codWo: {
type: DataTypes.STRING(20),
allowNull: false,
foreignKey: {
model: 'wo',
key: 'codWO'
}
},
codSparePart: {
type: DataTypes.STRING(30),
allowNull: false,
references: {
model: 'sparepart',
key: 'codSparePart'
}
},
quantity: {
type: DataTypes.FLOAT,
allowNull: true
},
date_request: {
type: DataTypes.DATEONLY,
allowNull: true
},
date_reception: {
type: DataTypes.DATEONLY,
allowNull: true
},
details: {
type: DataTypes.TEXT,
allowNull: true
},
codUser: {
type: DataTypes.STRING(20),
allowNull: false,
references: {
model: 'user',
key: 'codUser'
}
},
received: {
type: DataTypes.INTEGER(1),
allowNull: false
}
}, {
tableName: 'sparepart_request',
timestamps: false
});
/* sparepart_request.associate = function (models) {
models.sparepart_request.hasMany(models.sparepart, {foreignKey: 'codSparePart', targetKey: 'codSparePart'});
}; */
return sparepart_request;
};
Model wo.js:
/* jshint indent: 1 */
module.exports = function (sequelize, DataTypes) {
var wo = sequelize.define('wo', {
codWO: {
type: DataTypes.STRING(20),
allowNull: false,
primaryKey: true
},
codUser: {
type: DataTypes.STRING(20),
allowNull: false,
references: {
model: 'user',
key: 'codUser'
}
},
codOriginator: {
type: DataTypes.STRING(20),
allowNull: true,
references: {
model: 'user',
key: 'codUser'
}
},
capture_date: {
type: DataTypes.DATE,
allowNull: false
},
active: {
type: DataTypes.INTEGER(1),
allowNull: false
},
codType: {
type: DataTypes.CHAR(3),
allowNull: false,
references: {
model: 'type',
key: 'codType'
}
},
date: {
type: DataTypes.DATEONLY,
allowNull: false
},
title: {
type: DataTypes.STRING(255),
allowNull: true
},
date_finish: {
type: DataTypes.DATEONLY,
allowNull: true
},
codStatus: {
type: DataTypes.STRING(10),
allowNull: false,
references: {
model: 'status',
key: 'codStatus'
}
},
hours_planned: {
type: DataTypes.FLOAT,
allowNull: true
},
codElement: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'element',
key: 'codElement'
}
},
Security: {
type: DataTypes.INTEGER(1),
allowNull: true,
defaultValue: '0'
},
codEquipment: {
type: DataTypes.STRING(20),
allowNull: false,
references: {
model: 'equipment',
key: 'codEquipment'
}
},
codProject: {
type: DataTypes.INTEGER(11),
allowNull: false,
references: {
model: 'project',
key: 'id'
}
},
codTestRoom: {
type: DataTypes.STRING(10),
allowNull: false,
references: {
model: 'testroom',
key: 'codTestRoom'
}
}
}, {
tableName: 'wo',
timestamps: false
});
wo.associate = function (models) {
models.wo.belongsTo(models.wo_operation, {
as: 'wo_operation',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.belongsTo(models.dailyinfo_detail, {
as: 'dailyInfo',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.hasOne(models.wo_corrective, {
as: 'wo_corrective',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.hasOne(models.wo_preventive, {
as: 'wo_preventive',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.belongsToMany(models.sparepart_request, { as: 'WOSP', through: 'sparepart_request', foreignKey: 'codWO', otherKey: 'codSparePart' });
};
return wo;
};
Model sparepart.js
/* jshint indent: 1 */
module.exports = function (sequelize, DataTypes) {
var sparepart = sequelize.define('sparepart', {
codSparePart: {
type: DataTypes.STRING(30),
allowNull: false,
primaryKey: true,
references: {
model: 'sparepart_request',
key: 'codSparePart'
}
},
name: {
type: DataTypes.STRING(45),
allowNull: true
},
description: {
type: DataTypes.TEXT,
allowNull: true
},
available: {
type: DataTypes.INTEGER(1),
allowNull: false,
defaultValue: '1'
},
codManufacturer: {
type: DataTypes.INTEGER(11),
allowNull: false,
references: {
model: 'manufacturer',
key: 'codManufacturer'
}
},
stock: {
type: DataTypes.INTEGER(10),
allowNull: true
},
image_uri: {
type: DataTypes.STRING(500),
allowNull: true
},
codProject: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'project',
key: 'id'
}
},
price: {
type: DataTypes.FLOAT,
allowNull: false
}
}, {
tableName: 'sparepart',
timestamps: false
});
sparepart.associate = function (models) {
models.sparepart.belongsTo(models.manufacturer, {
foreignKey: 'codManufacturer',
targetKey: 'codManufacturer'
});
models.sparepart.belongsToMany(models.wo, { as: 'SPWO', through: 'sparepart_request', foreignKey: 'codSparePart', otherKey: 'codWO' });
};
return sparepart;
};
Here you can find my code, the three models and the query. at the moment I'm using postman I don't have anything in the frontEnd.
Here is one solution:
Remove id from sparepart_request.
Include the next code in sparepart_request:
sparepart_request.associate = function (models) {
models.sparepart_request.hasMany(models.sparepart, {foreignKey: 'codSparePart', targetKey: 'codSparePart'});
models.sparepart_request.hasMany(models.wo, {foreignKey: 'codWO', targetKey: 'codWO'});
};
Is it the correct way to do?, Apparently it is working...

Performing FULLTEXT search after JOIN operation in sequelize

I have two tables Category and Events and I want to perform a FULLTEXT search on the columns Events.Name,Description,Society and Category.Name after performing a join operation on both the tables in sequelize.
The modals have been defined as follows:
Events.js
(function () {
'use strict';
module.exports = function(sequelize, DataTypes) {
var Events = sequelize.define("Events", { //Must be same as table name
Id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true // Automatically gets converted to SERIAL for postgres
},
Name: {
type: DataTypes.STRING,
notNull: true
},
Description: {
type: DataTypes.STRING,
notNull: true
},
Venue: {
type: DataTypes.STRING,
notNull: true
},
StartTime: {
type: DataTypes.STRING,
notNull: true
},
EndTime: {
type: DataTypes.STRING,
notNull: true
},
StartDate: {
type: DataTypes.STRING,
notNull: true
},
EndDate: {
type: DataTypes.STRING,
notNull: true
},
CurrentRound: {
type: DataTypes.STRING,
notNull: true
},
Society: {
type: DataTypes.STRING,
notNull: true
},
CategoryId: {
type: DataTypes.INTEGER,
notNull: true
},
MaxContestants: {
type: DataTypes.INTEGER,
notNull: true
},
Status: {
type: DataTypes.STRING,
notNull: true
},
Pdf: {
type: DataTypes.STRING,
notNull: true
}
}, {
timestamps: false,
tableName: 'Events',
freezeTableName: true
}, {
indexes: [
{ type: 'FULLTEXT', fields: 'name' }
]
},{
classMethods: {
associate: function(models) {
Events.belongsTo(models.Category);
}
}
});
return Events;
};
}());
Category.js
module.exports = function(sequelize, DataTypes) {
var Category = sequelize.define("Category", {
Id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true // Automatically gets converted to SERIAL for postgres
},
Name: DataTypes.STRING
}, {
timestamps: false,
tableName: 'Category',
freezeTableName: true
},{
Indexes: [
{ type: 'FULLTEXT', fields: ['Name'] }
]
}, {
classMethods: {
associate: function(models) {
Category.hasMany(models.Events);
}
}
});
return Category;
};
The query I am performing is :
Model.Events.findAll({
include: [{ model: Model.Category }],having: ['MATCH(Events.Name,Description,Society,Category.Name) AGAINST(?)', query] }).then(function(data) {
console.log(JSON.stringify(data));
r.status = statusCodes.SUCCESS;
r.data = JSON.stringify(data);
return res.end(r.toString());
}).catch(function(err){
console.log(err);
r.status = statusCodes.SERVER_ERROR;
r.data = err;
return res.end(r.toString());
});
The errors I am getting are :
FULLTEXT index does not exits.
Incorrect arguments to the match.
I am not sure if a foreign key has been created.
Please help me out by correcting my query.