Sequelize.js foreign key
Solution 1
Before I had the same problem, and solved when I understood the functioning of settings Sequelize.
Straight to the point!
Suppose we have two objects: Person and Father
var Person = sequelize.define('Person', {
name: Sequelize.STRING
});
var Father = sequelize.define('Father', {
age: Sequelize.STRING,
//The magic start here
personId: {
type: Sequelize.INTEGER,
references: 'persons', // <<< Note, its table's name, not object name
referencesKey: 'id' // <<< Note, its a column name
}
});
Person.hasMany(Father); // Set one to many relationship
Maybe it helps you
Edit:
You can read this to understand better:
http://docs.sequelizejs.com/manual/tutorial/associations.html#foreign-keys
Solution 2
For Sequelize 4 this has been updated to the following:
const Father = sequelize.define('Father', {
name: Sequelize.STRING
});
const Child = sequelize.define('Child', {
age: Sequelize.STRING,
fatherId: {
type: Sequelize.INTEGER,
references: {
model: 'fathers', // 'fathers' refers to table name
key: 'id', // 'id' refers to column name in fathers table
}
}
});
Father.hasMany(Child); // Set one to many relationship
Edit: You can read more on associations at https://sequelize.org/master/manual/assocs.html
Solution 3
You need to add foreignKeyConstraint: true
Try:
MainClient.hasOne(MainDashboard, { foreignKey: 'idClient', foreignKeyConstraint: true })
Solution 4
I just tried to run your code, and the rows seem to be created fine:
CREATE TABLE IF NOT EXISTS `main_dashboard` (`title` VARCHAR(255), `id` INTEGER NOT NULL auto_increment , `idClient` INTEGER, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `main_client` (`id` INTEGER NOT NULL auto_increment, `clientId` INTEGER, PRIMARY KEY (`id`)) ENGINE=InnoDB;
clientId
is added to main_client
, and idClient
is added to main_dashboard
It seems you have slightly confused what the hasOne
method does. Each time you call hasOne
an association is created, so your code effectively associates the two tables twice. The method you are looking for is belongsTo
If you want each client to have one dashboard, the code would be the following:
MainClient.hasOne(MainDashboard, { foreignKey: 'clientId' })
MainDashboard.belongsTo(MainClient, { foreignKey: 'clientId' })
This creates a clientId
field on the main_dashboard
table, which relates to the id
field of the main_client
table
In short belongsTo
adds the relation to the table that you are calling the method on, hasOne
adds it on the table that is given as argument.
Solution 5
It's amazingly simple.
const MainDashboard = this.sequelize.define('main_dashboard', {/* attributes */}),
MainClient = this.sequelize.define('main_client', {/* attributes */});
MainDashboard.belongsTo(MainClient, { foreignKey: 'clientId' }); // Adds clientId to MainDashboard
It will link this as a foreign key and you may use it as an association. Let me know if I'm missing anything.
swampcypress
Updated on July 09, 2022Comments
-
swampcypress almost 2 years
When using Sequelize.js, the following code doesn't add any foreign key on tables.
var MainDashboard = sequelize.define('main_dashboard', { title: Sequelize.STRING }, { freezeTableName: true }) MainClient.hasOne(MainDashboard, { foreignKey: 'idClient' }) MainDashboard.hasOne(MainClient, { foreignKey: 'clientId' }) sequelize.sync({ force: true })
Is there any way to force Sequelize.js to add these foreign key constraints?
-
Philippe Hebert over 7 yearsThe use of
references
andreferencesKey
is now deprecated =>Utils deprecated Non-object references property found. Support for that will be removed in version 4. Expected { references: { model: "value", key: "key" } } instead of { references: "value", referencesKey: "key" }.
-
Buksy about 7 yearsthis is not a good example, last command says that
one Person has many Fathers
which doesnt sound natural -
The Red Pea over 5 yearsIs this still an option? I don't see the property
foreignKeyConstraint
in the API; onlyforeignKey
. Oh! Maybe the property is now called simply:constraints
? It is described as : "Should on update and on delete constraints be enabled on the foreign key. " -
Maksym Dudyk about 2 yearsI guess, we must also write down foreign key in parent model, that is MainClient, like this: MainClient.hasMany(MainDashboard, { foreignKey: 'clientId' }); We must also add column 'clientId' manually to the MainDashboard migration file with an attribute: 'type: DataTypes.INTEGER'.