tezvyn:

Sequelize Associations: Who Holds the Foreign Key?

AI-drafted, machine-checkedSource: sequelize.orgintermediate

Think of Sequelize associations as rules for foreign keys. `A.belongsTo(B)` means `A` holds the `bId` foreign key. `A.hasOne(B)` or `A.hasMany(B)` means `B` holds the `aId` key. The footgun is mixing these up, which breaks your database schema and queries.

WHY IT EXISTS ORMs like Sequelize need a way to translate object-oriented concepts (a User object having a 'posts' property) into the relational world of SQL tables and foreign keys. Associations are the bridge that automates this translation, creating and managing the necessary columns and constraints for you.

THE MENTAL MODEL The key isn't just that 'A is related to B'. The mental model is to ask: 'Which table stores the proof of this relationship?' The method you choose—belongsTo, hasOne, or hasMany—is a direct command telling Sequelize where to place the foreign key column. A.belongsTo(B) means table A gets a bId column. A.hasOne(B) means table B gets an aId column.

HOW IT WORKS Sequelize provides four main association methods. The model on which the method is called is the 'source', and the model passed as an argument is the 'target'.

A.belongsTo(B): Creates a one-to-one or many-to-one relationship. The foreign key is placed on the source model, A.

A.hasOne(B): Creates a one-to-one relationship. The foreign key is placed on the target model, B.

A.hasMany(B): Creates a one-to-many relationship. The foreign key is placed on the target model, B.

A.belongsToMany(B, { through: 'C' }): Creates a many-to-many relationship. A new junction table, C, is created to hold foreign keys from both A and B.

For full functionality, like being able to query the relationship from either model, you should define associations in pairs. For example, a one-to-many relationship is best defined with both User.hasMany(Post) and Post.belongsTo(User).

WHEN TO USE IT Use associations whenever you are modeling relationships between tables in a Node.js application with Sequelize. This is the bread and butter of the ORM. Examples include a User and their Profile (one-to-one), a Project and its Tasks (one-to-many), or an Article and its Tags (many-to-many).

WHEN NOT TO USE IT Avoid over-complicating things. If you just need to store a simple list of non-relational data, like a user's favorite colors, using a DataTypes.ARRAY(DataTypes.TEXT) column is simpler than creating a whole Colors table and association. For extremely complex or non-standard joins, a raw SQL query might be more direct and easier to debug.

ONE CANONICAL EXAMPLE The classic blog scenario: a User has many Posts, and each Post belongs to one User. This is a one-to-many relationship.

To model this, you define the associations in pairs: User.hasMany(Post); Post.belongsTo(User);

Sequelize interprets this and automatically adds a userId foreign key column to the Posts table. This setup enables you to use helper methods like someUser.getPosts() to fetch all related posts and somePost.getUser() to find the author, without writing the SQL joins yourself.

Read the original → sequelize.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.