hasMany() associations can not be define in Squelize.js? - mysql

This is the teacher Table's Schema
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../util/databaseConnection');
const Teacher = sequelize.define("teacher", {
teacherid: {
type: DataTypes.STRING,
allowNull: false,
primaryKey: true
},
surname: {
type: DataTypes.STRING,
allowNull: true
},
firstname: {
type: DataTypes.STRING,
allowNull: true
},
lastname: {
type: DataTypes.STRING,
allowNull: true
}
})
module.exports = Teacher;
This is the subject Model's Schema
const { Sequelize, DataTypes } = require("sequelize");
const sequelize = require('../util/databaseConnection');
const Subject = sequelize.define('subject', {
subjectid: {
type: DataTypes.INTEGER,
AutoIncrement: true,
primaryKey: true
},
subjectname: {
type: DataTypes.STRING
},
grade: {
type: DataTypes.STRING
},
subjectinfo: {
type: DataTypes.STRING
}
})
module.exports = Subject;
I need to define the association between teacher hasMany subject
Teacher.hasMany(Subject)
But following error
Naming collision between attribute 'subjects' and association
'subjects' on model teacher. To remedy this, change either foreignKey
or as in your association definition

You have to add Following keys
Teacher.hasMany(Subject, { foreignKey: 'teacher_id', targetKey: 'id' });
and in Subject model add following column
teacher_id: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: 'teacher',
key: 'id'
}
},

Related

How to define in my model an array of id from another table in mysql and sequelize

I create an api in express.js, node.js, mysql and sequelize.
I have two models : Custom fields and Customer Types
Here is my customer type model :
module.exports = (sequelize, DataTypes) => {
const CustomerType = sequelize.define("customerType", {
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING,
allowNull: false
},
user_id: {
type: DataTypes.STRING,
allowNull: false
}
})
return CustomerType
}
And there is my custom fields model :
const customerType = require('./customerTypeModel')
module.exports = (sequelize, DataTypes) => {
const CustomField = sequelize.define("customField", {
customer_type_ids: [
{
type: DataTypes.INTEGER,
references: {
model: customerType,
key: "id"
}
}
],
user_id: {
type: DataTypes.STRING,
allowNull: false
},
system_name: {
type: DataTypes.STRING,
allowNull: true
},
title: {
type: DataTypes.STRING,
allowNull: true
},
type: {
type: DataTypes.STRING,
allowNull: true
},
required: {
type: DataTypes.BOOLEAN,
allowNull: true
},
})
return CustomField
}
I need to have in my customField table an array of id from the customerType table.
For exemple i need to get a json like this :
{
"id": 1
"customer_types_ids": [
{
"id": 1,
"name": "Customers",
"description": "Customers",
"user_id": "123456"
},
{
"id": 2,
"name": "Leads",
"description": "Leads",
"user_id": "123456"
}
],
"user_id": "123456",
"system_name": "firstname",
"title": "Firstname",
"type": "text",
"required": true
}
How should I structure my custom field Model to be able to have a json like this in return?
Thanks for your help !
I assume you're expecting a One-to-Many relationship between CustomField and CustomerType. In this case, CustomerType owns the relation, so there is a reference to CustomField in the relational table of CustomerType called customFieldId.
// customerType.js
module.exports = (sequelize, DataTypes) => {
const CustomerType = sequelize.define("customerType", {
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING,
allowNull: false
},
user_id: {
type: DataTypes.STRING,
allowNull: false
}
});
return CustomerType;
}
// customField.js
module.exports = (sequelize, DataTypes) => {
const CustomField = sequelize.define("customField", {
user_id: {
type: DataTypes.STRING,
allowNull: false
},
system_name: {
type: DataTypes.STRING,
allowNull: true
},
title: {
type: DataTypes.STRING,
allowNull: true
},
type: {
type: DataTypes.STRING,
allowNull: true
},
required: {
type: DataTypes.BOOLEAN,
allowNull: true
},
});
return CustomField;
}
// db.js
...
const CustomerType = require("./customerType.js")(sequelize, Sequelize.DataTypes);
const CustomField = require("./customField.js")(sequelize, Sequelize.DataTypes);
CustomField.hasMany(CustomerType, { as: "customer_types_ids" });
CustomerType.belongsTo(CustomField, {
foreignKey: "id",
as: "customFieldId",
});
This should define two relational tables with a One-to-Many relationship. The following code can be used to load a CustomField with all its CustomerTypes.
CustomField.findByPk(id, { include: ["customer_types_ids"] });

Sequelize - ORM - Associations not working

Using Sequelize with MySQL. I have three models. Consultant, FamilyMember and Appointments. Appointment refers to Consultant and FamilyMember.
I have defined the foreign keys in the Appointment model. When the DB is created - the foreign keys are visible - when I check through a MySQL client, on the appointment table. The table names are freeze - so there isn't any chance of pluralization of the table names.
Consultant Model:
module.exports = (sequelize, DataTypes) => {
const consultant = sequelize.define('consultant', {
ID: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false
},
FirstName: {
type: DataTypes.STRING,
allowNull: false
},
LastName: {
type: DataTypes.STRING,
allowNull: false
}
{
freezeTableName: true
}
);
return consultant;
};
Appointment Model:
module.exports = (sequelize, DataTypes) => {
const appointment = sequelize.define('appointment', {
// attributes
ID: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false
},
ConsultantID: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: 'consultant',
key: 'ID'
}
},
FamilyMemberID: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: 'familymember',
key: 'ID'
}
}
},
{
freezeTableName: true
}
);
appointment.associate = function (models) {
models.appointment.belongsTo(models.consultant, {
foreignKey: 'ConsultantID',
as: 'consultant',
});
models.appointment.belongsTo(models.familymember, {
foreignKey: 'FamilyMemberID',
as: 'familymember',
});
};
return appointment;
};
Family Member model:
module.exports = (sequelize, DataTypes) => {
const familymember = sequelize.define('familymember', {
// attributes
ID: {
primaryKey: true,
type: DataTypes.UUID,
allowNull: false
},
FamilyID: {
type: DataTypes.UUID,
allowNull: false
},
FirstName: {
type: DataTypes.STRING,
allowNull: false
},
LastName: {
type: DataTypes.STRING,
allowNull: false
}
},
{
freezeTableName: true
}
);
return familymember;
};
Then in the code I try to fetch appointment and get the related familymember and consultant like this
var appointments = await Appointment.findAll({
where: {
AppointmentDateConfirmed: {
$gte: moment().subtract(0, 'days').toDate()
}
}, include:[Consultant, FamilyMember]
}
)
However I get an error
UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError: consultant is not associated to appointment!
I suppose you should register your associations after models registration like I pointed in this answer

Sequelize hasMany is working fine but the inverse relation is not working

I am trying to work with mysql relations in Node Js(express Js) using Sequelize.
User.hasMany(Post); work just fine, but when i try to inverse it in Post model like: Post.belongsTo(User);
got this error:
throw new Error(${source.name}.${_.lowerFirst(Type.name)} called with something that's not a subclass of Sequelize.Model);
Error: post.belongsTo called with something that's not a subclass of Sequelize.Model
User model like:
const Sequelize = require('sequelize');
const db = require('../config/db');
const Post = require('./Post');
const User = db.define('user', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
notNull: true,
primaryKey: true
},
name: {
type: Sequelize.STRING,
notNull: true
},
email: {
type: Sequelize.STRING,
notNull: true
},
password: {
type: Sequelize.STRING,
notNull: true
}
});
User.hasMany(Post);
module.exports = User;
And Post model like:
const Sequelize = require('sequelize');
const db = require('../config/db');
const User = require('./User');
const Post = db.define('post', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
notNull: true,
primaryKey: true
},
title: {
type: Sequelize.STRING,
notNull: true
},
description: {
type: Sequelize.TEXT,
notNull: true
},
author: {
type: Sequelize.STRING,
notNull: true
}
});
Post.belongsTo(User);
module.exports = Post;
How can i solve this problem?
Thanks everyone...
You should correct your model definition exports as functions and define associate function in each model definition function like this and call it all after all models are registered in some module like database.js:
user.js
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('user', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
notNull: true,
primaryKey: true
},
...
User.associate = function (models) {
User.hasMany(models.Post)
}
post.js
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('post', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
notNull: true,
primaryKey: true
},
...
Post.associate = function (models) {
Post.belongsTo(models.User)
}

Problem coding a weak entity in sequelize

I am creating a cinema application. I have modeled the database on mySql but I am having trouble migrating it to Sequelize. I have followed the documentation but I am getting a lot of different errors.
I have tried using associations and indexes (as it should be). This is the model I am trying to make.
OCCUPIED_SEATS is composed of only two foreign keys and both make a unique index.
OCCUPIED_SEATS:
const SEATS = require("./Seats");
const SCREENING = require("./Screening");
const OCCUPIED_SEATS = sequelize.define("OCCUPIED_SEATS", {
//SEATS_ID
//SCREENING_ID
},
{
indexes: [
{
unique: true,
fields: [SEAT_ID, SCREENING_ID]
}
],
underscored: true
}
);
module.exports = OCCUPIED_SEATS;
SEATS:
const OCCUPIED_SEATS = require("./Occupied_Seats");
const SEATS = sequelize.define("SEATS", {
SEATS_ID: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true
},
ROW: {
type: Sequelize.STRING,
allowNull: false,
},
COLUMN: {
type: Sequelize.INTEGER,
allowNull: false
},
},
{
underscored: true
}
);
SEATS.hasMany(OCCUPIED_SEATS, {foreignKey: 'SEAT_ID'})
module.exports = SEATS;
SCREENING:
const OCCUPIED_SEATS = require("./Occupied_Seats");
const SCREENING = sequelize.define("SCREENING", {
SCREENING_ID: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true
},
SCREENING_START_TIME: {
type: Sequelize.TIME,
allowNull: false,
},
DATE: {
type: Sequelize.DATE,
allowNull: false
}
},
{
underscored: true,
indexes: [
{
unique: true,
fields: [ROOM_ID, SCREENING_START_TIME, DATE]
}
]
}
);
SCREENING.hasMany(OCCUPIED_SEATS, {foreignKey: 'SCREENING_ID'});
module.exports = SCREENING;
The error I am getting when I try this is:
[💻] Error: SEATS.hasMany called with something that's not a subclass of Sequelize.Model
How should I code the model?
Looks like in the new version of Sequelize you have to define your models through Sequelize.Model type:
class Seats extends Sequelize.Model {}
Seats.init({
id: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true
},
row: {
type: Sequelize.STRING,
allowNull: false,
},
...
});
module.exports = Seats;
And then somewhere else:
Seats.hasMany(OccupiedSeatc, {foreignKey: 'SEAT_ID'})
See model definition docs and accociation docs.

How to add foreign key using sequelize mysql

"I have 2 tables "Users" and "Profile_personals". How do I add a foreign key constraint to my profile personals using my "user_id" primary that's inside my Users table? I'm working with node.js, sequelize mysql.
Users(parent Table):
const Sequelize = require('sequelize')
const db = require("../database/db.js")
module.exports = db.sequelize.define(
"users",
{
user_id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
}
},
{
timestamps: false
}
)
Personals(Child Table):
const Sequelize = require('sequelize')
const db = require("../database/db.js")
module.exports = db.sequelize.define(
'profile_personals',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
biography: {
type: Sequelize.STRING
}
},
{
timestamps: false
}
)
Do it this way, I hope it's what you're looking for.
module.exports = db.sequelize.define(
'profile_personals',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
biography: {
type: Sequelize.STRING
},
// It is possible to create foreign keys:
user_id: {
type: Sequelize.INTEGER,
references: {
// This is a reference to another model
model: Users,
// This is the column name of the referenced model
key: 'user_id'
}
}
},
{
timestamps: false
}
);