Reputation: 637
I have two tables, apps
and services
. On services
the PRIMARY KEY is set to field called orn
.
I created a through table between these two tables called apps_services
with appId
and serviceId
appId: {
type: Sequelize.UUID,
references: {
model: 'apps',
key: 'id'
}
},
serviceId: {
type: Sequelize.STRING,
references: {
model: 'services',
key: 'orn'
}
},
But here is a problem, when i use app.addService(foundService);
(this creates a relationship between that app instance and foundService). When i used node debugger, i found out that sequelize tried inserting an id
into serviceId
instead of an orn
Executing (default): INSERT INTO "apps_services" ("id","appId","serviceId","createdAt","updatedAt") VALUES ('8d85f9b9-b472-4165-a345-657a0fe0d8ad','49f3daa4-1df4-4890-92f8-9a06f751ffb7','8cab340d-d11b-4e3b-842c-aeea9a28c368','2021-02-16 00:22:17.919 +00:00','2021-02-16 00:22:17.919 +00:00') RETURNING "id","appId","serviceId","userId","selfGranted","createdAt","updatedAt";
the third value in the bracket, the problem is id
is not the foreignKey but orn
is
below is the service
table, we can see the orn
column, which is the PRIMARY KEY and foreign key linking to the apps_services table.
Is there a way to force sequelize to use the orn
field?
module.exports = (sequelize, DataTypes) => {
const apps_services = sequelize.define('apps_services', {
id: {
type: DataTypes.UUID,
defaultValue: new DataTypes.UUIDV4(),
unique: true,
primaryKey: true
},
appId: {
type: DataTypes.UUID,
},
serviceId: {
type: DataTypes.STRING,
},
userId: {
type: DataTypes.UUID
},
selfGranted: DataTypes.BOOLEAN
}, {
timestamps: true
});
apps_services.associate = function (models) {
models.apps.belongsToMany(models.services, {
through: apps_services
});
models.services.belongsToMany(models.apps, {
through: apps_services
});
};
//apps_services.sync({alter: true});
return apps_services;
};
// this is apps_services migration
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('apps_services', {
id:{
type: Sequelize.UUID,
defaultValue: new Sequelize.UUIDV4(),
unique: true,
primaryKey: true
},
appId: {
type: Sequelize.UUID,
references: {
model: 'apps',
key: 'id'
}
},
serviceId: {
type: Sequelize.STRING,
references: {
model: 'services',
key: 'orn'
}
},
userId: {
type: Sequelize.UUID,
references: {
model: 'Users',
key: 'id'
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
},
selfGranted: Sequelize.BOOLEAN,
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('apps_services');
}
};
Below is the services table
Upvotes: 0
Views: 1300
Reputation: 864
Yes you can mention which field to use from the opposite table.
apps_services.associate = function (models) {
// you can move this association to apps model file
models.apps.belongsToMany(models.services, {
// Reference: https://sequelize.org/master/class/lib/model.js~Model.html#static-method-belongsToMany
through: 'apps_services',
foreignKey: 'appId', // <-- add this
});
// you can move this association to services model file
models.services.belongsToMany(models.apps, {
through: 'apps_services',
foreignKey: 'serviceId', // <-- add this - name of field in through table
otherKey: 'orn', // <-- add this - name of field in source table
});
/**
* new relation below just to complete the Many to Many relation
*/
// you can add this association in app_services model file
models.apps_services.belongsTo(models.services, {
// Reference: https://sequelize.org/master/class/lib/model.js~Model.html#static-method-belongsTo
foreignKey: 'serviceId', // <--- name of field in source table
targetKey: 'orn', // <--- name of field in target table
});
// you can add this association in app_services model file
models.apps_services.belongsTo(models.apps, {
foreignKey: 'appId', // <--- name of field in source table
// targetKey: 'id', //(not needed as already primary key by default) <--- name of field in target table
});
};
Upvotes: 1