Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize hasMany, belongsTo, or both?

I want to properly setup one-to-one or one-to-many relationship with sequelize and as a matter of fact it all seems to be working just fine if i use either one of hasOne/ hasMany or belongsTo in my model definition. For example the following associations do create the userId field on their Targets:

    User.hasMany(Email, {
        as: 'emails',
        foreignKey: 'userId',
    })

    User.hasOne(Profile, {
        as: 'profile',
        foreignKey: 'userId',
    })

But almost everywhere in official docs i see something like:

   Projects.hasMany(Tasks);
   Tasks.belongsTo(Projects);

i.e. hasMany AND belongsTo are being used together.

Is this really required or it is enough to use just one of them? Any further explanation would be really valuable. Thanks!

like image 421
ZenDD Avatar asked Jul 29 '17 13:07

ZenDD


People also ask

What is Sequelize hasMany?

The Sequelize hasMany() method is used to create a One-To-Many association between two Sequelize models. For example, suppose you have SQL tables named Countries and Cities in your database. These two tables are related where one country row can have many city rows.

How do you use belongsTo in Sequelize?

You can make the Task model belongs to the User model by calling the belongsTo() method from the Task model like this: Task. belongsTo(User); The belongsTo() method above will associate the Task model with the User model, adding the UserId attribute to the Task model as the foreign key constraint.

How do you include two models in Sequelize?

Your solution, along with using include: {all:true} in my findAll query, did the trick. instead of using include: {all:true} in findAll you can use include: {model: models. User, as: 'createdByUser'} , etc. Be sure to use as: in all associations to the same model in your Sequelize model declaration.

What is a one-to-many relationship in Sequelize?

To create a One-To-One relationship, the hasOne and belongsTo associations are used together; To create a One-To-Many relationship, the hasMany and belongsTo associations are used together; To create a Many-To-Many relationship, two belongsToMany calls are used together.


1 Answers

Using belongsTo defines the ownership of the associated models. To explain this in more detail I will refer to the example cited from the tutorials

Project.hasMany(Task);
Task.belongsTo(Project);

Assume that you are no longer interested in the tasks of a deleted project. In that case you would have to delete the tasks manually, had you not defined the belongsTo association. belongsTo establishes an ownership of projects over it's tasks and the database will automatically delete the tasks belonging to the deleted project as well. This is called cascading delete and can chain over multiple tables.

If you run the following code snippet

const Project = sequelize.define('project', {
    name: Sequelize.STRING
});
const Task =  sequelize.define('task', {
    name: Sequelize.STRING
});
Project.hasMany(Task);
Task.belongsTo(Project);

in a sequelize script and watch the output

Executing (default): DROP TABLE IF EXISTS `projects`;
Executing (default): CREATE TABLE IF NOT EXISTS `projects` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`projects`)
Executing (default): DROP TABLE IF EXISTS `tasks`;
Executing (default): CREATE TABLE IF NOT EXISTS `tasks` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `projectId` INTEGER REFERENCES `projects` (`id`) ON DELETE SET NULL ON UPDATE CASCADE);

you will notice the cascading behaviour being set in the creation of the tasks table.

So much said, the final answer is: it depends. The use of belongsTo can come very handy or will be fatal if you would rather keep the tasks of the deleted project. Only use belongsTo if it makes sense in the context of your application.

like image 104
chriopp Avatar answered Sep 25 '22 18:09

chriopp