Sequelize double relationships - node.js

I'm doing a node.js project that allows virtual trading between user.
A User can have many trades. Each Trade will have to contain 2 fk from User, which are the id of the seller as well as the buyer.
I'm using sequelize in node.js to build up the model.
const { Sequelize, DataTypes, Model } = require('sequelize');
import {sequelize} from '../database/connection.js';
const User = sequelize.define('User', {
// Model attributes are defined here
id:{
type: DataTypes.INTEGER(11),
allowNull: false,
autoIncrement: true,
primaryKey: true
},
}, {
// Other model options go here
sequelize, // We need to pass the connection instance
freezeTableName: true
});
module.exports = User
///////////////////////////////////////////
// Trade
const { Sequelize, DataTypes, Model } = require('sequelize');
import {sequelize} from '../database/connection.js';
const Trade = sequelize.define('Trade', {
// Model attributes are defined here
id:{
type: DataTypes.INTEGER(11),
allowNull: false,
autoIncrement: true,
primaryKey: true
},
isPaid:{
type: DataTypes.BOOLEAN,
defaultValue: true
}
// fk are in relationships.js
}, {
// Other model options go here
sequelize, // We need to pass the connection instance
freezeTableName: true
});
module.exports = Trade
/////////////////////////////////////
//relationships
User.hasMany(Trade,{
foreignKey: "offererId"
})
Trade.belongsTo(User);
//
User.hasMany(Trade,{
foreignKey: "receiverId"
})
Trade.belongsTo(User);
Is this a right solution?

Using a super M:N may be your most versatile option.
User.belongsToMany(User, { through: Trade, as: "offerer", foreignKey: "offererId"})
User.belongsToMany(User, { through: Trade, as: "receiver", foreignKey: "receiverId"})
Trade.belongsTo(User)
User.hasMany(Trade)
This allows you to use the auto-generated association methods and query user on user.

Related

one-to-many relationship with sequelize

I have 2 tables, users and users_signature where the signature takes several applications and I need to make a select according to the application.
Models:
user
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = require('./user_has_signature');
const Usuario = database.define('usuario', {
usu_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
usu_rg: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User.hasMany(User_has_signature, {as: 'user_has_signature'});
module.exports = User;
User_has_signature
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = database.define('user_has_signature', {
usu_has_signature_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
user_usu_id: {
type: Sequelize.STRING,
},
signature_aplicativo_signature_aplicativo_id: {
type: Sequelize.STRING,
},
signature_type_signature_type_id: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User_has_signature.associate = (models) => {
User_has_signature.belongsTo(models.User,
{ foreignKey: 'user_usu_id', as: 'users' });
};
module.exports = User_has_signature;
Controller
UserController
const User = require("../../model/user/user")
const User_has_signature = require("../../model/user/user_has_signature")
async index(req, res){
const user = await User.findAll({
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
through: {
where: {signature_ttype_signature_type_id: 3}
}
}]
})
res.status(200).json(user)
return
}
The error that is returning to me in the terminal is: (node:15168)
UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError:
user_has_signature is associated to usuario using an alias. You must
use the 'as' keyword to specify the alias within your include
statement
I think you have to specify the alias you have given when writing your query :
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
as : 'users'
through: {
where: {signature_ttype_signature_type_id: 3}
}]
Either way I'm using Sequelize more in Typescript, so I'm not sure of the syntax.
The way it handles One to Many relationship isn't the clearest I've seen (Like Symfony or Spring)

How to create an object of a relationship in sequelize?

Hey I need to create a relationship in sequelize. I have the model and is well created in the database.
I'll show you my models but it's not very relevant.
Seller Model
const Sellers = db.define("sellers", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: Sequelize.STRING,
surname: Sequelize.STRING,
});
Sellers.hasMany(Clients);
module.exports = Sellers;
Client Model
const Client = db.define("clients", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: Sequelize.STRING,
creationDate: Sequelize.DATE,
client_type: Sequelize.STRING,
});
module.exports = Client;
What I want to do is simply make a relation between the client and seller. In the database a SellerId is added in the client table because of sequelize hasMany() method. What I want to do is just be able to pass the id to the ORM when creating a client so it makes the relationship automatically to the seller table.
Sequelize Documentation about this
Thank you for taking your time to read this. I hope you can help me! Have a great day.
First of all I'd prefer to define a foreign key column in a model and indicate it in associations explicitly. And of course you need to add another association from clients to sellers - belongsTo and call both of associations outside models to be able to reference them to each other.
Client model file:
const Client = db.define("clients", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: Sequelize.STRING,
creationDate: Sequelize.DATE,
client_type: Sequelize.STRING,
sellerId: {
type: Sequelize.INTEGER,
allowNull: false // or true if this association is optional
},
});
some database.js file where you should register all associations:
....
Sellers.hasMany(Clients, { foreignKey: 'sellerId' });
Clients.belongsTo(Sellers, { foreignKey: 'sellerId' });
And then you can create a client indicating a seller's id:
const seller = await Seller.findOne({
where: {
name: 'Peter'
}
})
const newClient = await Client.create({
name: 'John',
sellerId: seller.id,
// other fields here
})

Persist constraint unique after destroy

I have a users table with the unique username. When I delete the users and recreate the same users the error appears:
Error: SQLITE_CONSTRAINT: UNIQUE constraint failed
It seems that unique count of the username is persistent after destroy. Is there a way to remove this constraint after deleting?
I have seen in the sequelize documentation that hooks exist but I don't quite understand how to apply it
UPDATE
const Sequelize = require('sequelize');
// Connection
const { sequelize } = require('../config/sequelize');
const UserSource = require('./UserSource');
const User = sequelize.define('user', {
user_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
},
username: {
type: Sequelize.STRING(100),
unique: true,
},
name: {
type: Sequelize.STRING(100)
},
place_id: {
type: Sequelize.INTEGER,
allowNull: false,
},
}, {
paranoid: true,
timestamps: false,
});
User.hasMany(UserSource, { foreignKey: 'user_id', sourceKey: 'user_id'});
UserSource.belongsTo(User, { foreignKey: 'user_id', sourceKey: 'user_id'});
module.exports = User;
I've also tried paranoid: false and it still doesn't work

How to Perform Multiple Inner Joins in Sequelize Postgresql

Am newbie to RDBMS and Sequelize as well wanted to explore more in those now am struck up with JOINS. I don't know how to perform JOINS via SEQUELIZE. I have 3 tables USERS,ORDERS,PRODUCTS ORDERS table contains USERS,PRODUCTS primary key as its foreign key. Am attaching my model code below
User Model
const Sequelize = require('sequelize');
const sequelize = require('../config');
let Users = sequelize.define('users', {
id : {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: {
type: Sequelize.STRING,
},
password: {
type: Sequelize.STRING
}
});
module.exports = Users;
Products Model
const Sequelize = require('sequelize');
const sequelize = require('../config');
let products=sequelize.define('products', {
id : {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
category : {
type: Sequelize.STRING,
allowNull: false
},
name : {
type: Sequelize.STRING,
allowNull: false
},
price: {
type: Sequelize.INTEGER,
allowNull: false
}
});
module.exports= products;
Orders Model
const Sequelize = require('sequelize');
const sequelize = require('../config');
let users=require('./user');
let products=require('./product');
let orders=sequelize.define('orders', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: Sequelize.INTEGER,
references: {
model: 'users',
key: 'id'
}
},
product_id: {
type: Sequelize.INTEGER,
references: {
model: 'products',
key: 'id'
}
},
price: {
type: Sequelize.INTEGER,
allowNull: false
}
});
module.exports= orders;
I want this following raw query to be performed via SEQUELIZE
SELECT * FROM ((orders INNER JOIN users ON users.id=orders.user_id) INNER JOIN products ON products.id=orders.product_id);
I have looked at the documentation but i couldn't figure out how to do it. ANy help is appreciated. Thanks
First thing you need to do is set up your Associations.
So lets break this up in to parts. We know that your ORDERS table contains the id for a USER and a PRODUCT. So this is how you would set up your associations for these tables.
I am assuming that a user has many orders. We make the associations in both directions.
User.hasMany(Orders, {foreignKey: 'user_id'});
Order.belongsTo(User, {foreignKey: 'user_id'});
You have the model correctly defined it seems.
Now in order to do a join, after setting up the associations, we want to set up a query to do joins for tables. Now keep in mind this would be done in your controller.
// Make sure you import your models up here to use below
export function getRequestsByWeek(req, res) {
return order.findAll({
include: [
{model: users, attributes: []}, // nothing in attributes here in order to not import columns from users
{model: products} // nothing in attributes here in order to not import columns from products
],
attributes: ['id'], //in quotes specify what columns you want, otherwise you will pull them all
// Otherwise remove attributes above this line to import everything.
})
.then(respondWithResult(res))
.catch(handleError(res));
}
let users=require('./user');
let products=require('./product');
export function getOrders(req, res) {
return order.findAndCountAll({
include: [
{model: users, required: true}, // true for INNER JOIN
{model: products, required: false} // false for LEFT OUTER JOIN
],
them all
})
}

Sequelize.js: One to Many relationship eager load with custom field

I am writting an app with node, express, sequelize and I have a little problem. I am trying to eager load a model on the "one part" of the relationship.
I get this SQL:
Executing: SELECT `albaran`.*, `cliente`.`ClienteID` AS `cliente.ClienteID`,
`cliente`.`NombreES` AS `cliente.NombreES` FROM `albaran` LEFT OUTER JOIN `cliente` AS
`cliente` ON `albaran`.`AlbaranNo` = `cliente`.`ClienteID` WHERE
`albaran`.`AlbaranNo`='2013100001';
and I need it to be:
Executing: SELECT `albaran`.*, `cliente`.`ClienteID` AS `cliente.ClienteID`,
`cliente`.`NombreES` AS `cliente.NombreES` FROM `albaran` LEFT OUTER JOIN `cliente` AS
`cliente` ON `albaran`.`ClienteID` = `cliente`.`ClienteID` WHERE
`albaran`.`AlbaranNo`='2013100001';
So I could access it at the view (now I get an empty string):
#{albaran.cliente.NombreES}
This is the code:
albaran.js
module.exports = function(sequelize, DataTypes) {
return sequelize.define("Albaran", {
AlbaranNo: { type: DataTypes.BIGINT, primaryKey: true},
ClienteID: {
type: DataTypes.STRING, //this must be string, I am not who defined the db
references: "Cliente",
referencesKey: "ClienteID"
}},{
timestamps: false,
freezeTableName: true,
tableName: 'albaran'
})
}
cliente.js
module.exports = function(sequelize, DataTypes) {
return sequelize.define("Cliente", {
ClienteID: {
type: DataTypes.STRING, primaryKey: true
},
NombreES: DataTypes.STRING
},{
timestamps: false,
freezeTableName: true,
tableName: 'cliente'
})
}
associations
db.Albaran.hasOne(db.Cliente, {as: "cliente", foreignKey: 'ClienteID'});
router
exports.albaran = function(req, res) {
db.Albaran.findAll({ include: [{ model: db.Cliente, as: "cliente" }]})
.success(function (albaranes){
res.render("albaranes", {albaranes: albaranes});
});
};
Thank you very much. I hope I explained myself clearly.
Edition:
I found the solution modifying the association:
db.Albaran.belongsTo(db.Cliente, {as: "cliente", foreignKey: 'ClienteID', primaryKey: 'ClienteID'});
db.Cliente.hasMany(db.Albaran, {as: "albaranes", foreignKey: 'ClienteID'});
Thank you everyone
This may be it:
db.Cliente.hasMany(db.Albaran, {as: "albaran", foreignKey: 'ClienteID'});
More info here: http://sequelizejs.com/documentation#associations-one-to-many
The other side is:
db.Albaran.hasOne(db.Cliente, {as: "cliente", foreignKey: 'AlbaranNo"});

Resources