Associate different models using sequelize? - node.js

Hi I am trying to associate my User model with login model and Question_details models.But if i am using the Question_details association then i am geeting eagerLodingError :user is not associated to login but if i am commenting it then it works fine so how can i associate it ?
But if i am associating with
User Model
module.exports = (sequelize, DataTypes) => {
var Users = sequelize.define('users', {
name: {
type: DataTypes.STRING(100)
}
phone: {
type: DataTypes.BIGINT,
unique: true
}
}, { freezeTableName: true });
Users.associate = function(models) {
Users.hasOne(models.login, {
foreignKey: 'user_id',
as: 'loginDetails'
});
};
Users.associate = function(models) {
Users.hasMany(models.customer_query, {
foreignKey: 'user_id',
as: 'queryDetails'
});
};
return Users;
};
LOGIN MODEL
module.exports = (sequelize, DataTypes) => {
var Login = sequelize.define('login', {
user_id: {
type: DataTypes.INTEGER
},
user_name: {
type: DataTypes.STRING(500),
isEmail: true
},
password: {
type: DataTypes.STRING(500)
},
role_id: {
type: DataTypes.INTEGER
}
}, {
underscored: true,
freezeTableName: true
});
Login.associate = function(models) {
Login.belongsTo(models.users, {
foreignKey: 'user_id',
onDelete: 'CASCADE'
});
};
Login.associate = function(models) {
Login.belongsTo(models.roles, {
foreignKey: 'role_id',
onDelete: 'CASCADE'
});
};
return Login;
};
questionDetails Model
module.exports = function(sequelize, DataTypes) {
var questionDetails = sequelize.define('question_details', {
query_id: {
type: DataTypes.INTEGER
},
ques_type_id: {
type: DataTypes.INTEGER
},
created_by: {
type: DataTypes.INTEGER
},
question: {
type: DataTypes.TEXT
},
}, { freezeTableName: true });
questionDetails.associate = function(models) {
questionDetails.belongsTo(models.users, {
foreignKey: 'created_by',
onDelete: 'CASCADE'
});
};
return questionDetails;
};

You only have to define associate once. When you define it the second time you're actually overwriting it. So for the User model you should actually do...
Users.associate = function(models) {
Users.hasOne(models.login, {
foreignKey: 'user_id',
as: 'loginDetails'
});
Users.hasMany(models.customer_query, {
foreignKey: 'user_id',
as: 'queryDetails'
});
};
Do similarly for your login model as you are also overwriting the associate function there.
Good luck! :)

Related

Sequelize Cannot Access "projectuser" before initialization

sirs. I have 2 models in sequelize ,Project and User. Relationship between this two models is many-to-many. Fot this relation, I have created projectuser. But when i trying to insert intoprojectuser console gives me ReferenceError: Cannot access 'projectuser' before initialization error. [NodeJs][Sequelize] ReferenceError: Cannot access 'ModelName' before initialization I have tried this solution but i think it is too complex solution. Can you please help me?
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class Project extends Model {
static associate(models) {
const { User, Issue, projectuser } = models;
this.belongsToMany(User, {
as: "project_users",
foreignKey: "project_id",
through: "projectuser",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.hasMany(Issue, {
as: "project_issues",
foreignKey: "project_id",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
Project.init(
{
project_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
projectname: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.TEXT,
},
projecturl: {
type: DataTypes.STRING,
},
},
{
sequelize,
modelName: "Project",
}
);
return Project;
};
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
const { Commet, Project, Issue, projectuser, issueuser } = models;
this.hasMany(Commet, {
foreignKey: "user_id",
as: "user_commets",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.belongsToMany(Project, {
as: "project_user",
foreignKey: "user_id",
through: "projectuser",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.belongsToMany(Issue, {
as: "user_issues",
foreignKey: "user_id",
through: issueuser,
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
User.init(
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
validate: {
roleValidator(role) {
let rolet = role.toLowerCase();
if (roles[rolet] === undefined) {
throw new Error("Invalid Role");
}
},
},
},
username: { type: DataTypes.STRING, allowNull: false },
usersurname: { type: DataTypes.STRING, allowNull: false },
avatarURL: { type: DataTypes.STRING, allowNull: true },
password: {
type: DataTypes.STRING,
validate: {
passwordValidator(password) {
if (password.length <= 5) {
throw new Error("Cannot be less than 5 characters");
}
},
},
},
email: {
type: DataTypes.STRING,
unique: true,
validate: { isEmail: true },
},
},
{
sequelize,
modelName: "User",
}
);
return User;
};
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class projectuser 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
}
}
projectuser.init({
deneme: DataTypes.STRING
}, {
sequelize,
modelName: 'projectuser',
});
return projectuser;
};

How to use Sequelize belongsTo

I have simple sequelize models like below.
// user.js
module.exports = function(sequelize, DataTypes) {
const user = sequelize.define(
"User",
{
name: {
field: "name",
type: DataTypes.STRING(50),
unique: true,
allowNull: false
},
uid: {
field: "uid",
type: DataTypes.STRING(50),
allowNull: false
}
},
{
freezeTableName: true,
tableName: "user"
}
);
user.associate = function(models) {
user.hasMany(models.friend, {
foreignKey: "uid"
});
};
return user;
};
And there is another model.
// friend.js
module.exports = function(sequelize, DataTypes) {
const friend = sequelize.define(
"Friend",
{
uid: {
field: "uid",
type: DataTypes.STRING(50),
allowNull: false
},
jsonId: {
field: "json-id",
type: DataTypes.STRING(50),
allowNull: true
},
nlpId: {
field: "nlp-id",
type: DataTypes.STRING(50),
allowNull: true
}
},
{
freezeTableName: true,
tableName: "friend"
}
);
friend.associate = function(models) {
friend.belongsTo(models.user, { foreignKey: "uid" });
};
return friend;
};
And there is index.js. When I run sequelize, it gives me an error like "Error: Friend.belongsTo called with something that's not a subclass of Sequelize.Model".
Could you recommend some advice for this problem? Thank you so much for reading it.
db.user = require('./user')(sequelize, Sequelize);
db.friend = require('./friend')(sequelize, Sequelize);
Write to the user model
User.associate = models => {
User.hasMany(models.Friend, {
as: 'friends',
foreignKey: 'userId'
});
};
Write to the friend model
Friend.associate = models => {
Friend.belongsTo(models.User, {
as: 'friend',
foreignKey: 'userId'
});
};

Can't delete all from Sequelize n:m associated table

I am trying to delete all contents from a n:m association table.
I have the tables: MenuItems and UserGroups like this, but I am using migrations to genererate the database:
MenuItems
module.exports = (sequelize, DataTypes) => {
const MenuItems = sequelize.define('MenuItems', {
title: {
type: DataTypes.STRING,
allowNull: false
}
// more fields...
}, {
freezeTableName: true
});
MenuItems.associate = function(models) {
MenuItems.belongsToMany(models.UserGroups, { through: 'MenuItemUserGroups' });
};
UserGroups
module.exports = (sequelize, DataTypes) => {
const UserGroups = sequelize.define('UserGroups', {
name: {
type: DataTypes.STRING,
unique: true
}
}, {
freezeTableName: true
});
UserGroups.associate = function(models) {
// Associations to other models
UserGroups.belongsToMany(models.MenuItems, { through: 'MenuItemUserGroups' });
};
return UserGroups;
};
The association table is generated with the following migration:
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('MenuItemUserGroups', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
menuItemId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'MenuItems',
key: 'id'
},
onUpdate: 'cascade',
onDelete: 'cascade'
},
userGroupId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'UserGroups',
key: 'id'
},
onUpdate: 'cascade',
onDelete: 'cascade'
}
//more fields
});
}
I try to delete using the following sequelize code:
models.MenuItems.findOne({ where: { id: 1 }, include: [{ all: true }] }).then(menuItem => {
if(req.body.userGroups.length <= 0) {
menuItem.setUserGroups([]).then(result => {
console.log(result);
});
The SQL that is generated is the following:
DELETE FROM `MenuItemUserGroups` WHERE `UserGroupId` = 1 AND `MenuItemId` IN (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
[ 0 ]
where UserGroupId IN (NULL) will always return nothing. If that part is removed, the query works.
Could this have something to do with some naming convention?

Retrieve sequelize rows through a many-to-many relationship table

I have two models Company and Contractor linked through a CompanyContractor relational table.
company.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const Company = sequelize.define('Company', {
name: {
type: DataTypes.STRING(30),
allowNull: false,
unique: true
},
slug: {
type: DataTypes.STRING(30),
allowNull: false
},
description: DataTypes.STRING(200),
}, {});
Company.associate = function(models) {
Company.belongsToMany(models.Contractor, { through: 'CompanyContractor', as: 'contractors',foreignKey: 'companyId' });
};
return Company;
};
contractor.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const Contractor = sequelize.define('Contractor', {
name: {
type: DataTypes.STRING(50),
allowNull: false
}
}, {});
Contractor.associate = function(models) {
Contractor.belongsToMany(models.Company, { through: 'CompanyContractor', as: 'contractors' });
};
return Contractor;
};
companyContractor.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const CompanyContractor = sequelize.define('CompanyContractor', {
companyId: {
type: DataTypes.INTEGER,
allowNull: false
},
contractorId: {
type: DataTypes.INTEGER,
allowNull: false
}
}, {
timestamps: false
});
return CompanyContractor;
};
Is there a way to Contractor.findAll() through companyId?
Contractor.findAll({
include: [{
model: Company,
through: {
attributes: ['companyId']
}
}]
});
From the documentation

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