Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to customize association methods in sequelize

Let's say I have a users and projects. Than I create a 1:m association between them.

const User = sequlize.define("user", {...})
const Project = sequelize.define("project". {...})

User.hasMany(Project, { as: "projects" })

Than sequelize creates the

addProject 

method for me automatically.

In other scenarios I might want a custom function for that.

For example might I want to check if this user is allowed to pick up the project.

In other scenarios I might also want to prevent sequelize from adding these association methods to my object.

My questions:

  1. Is there a way to create a custom association method, if not can I at least define a validation method?

  2. Can I prevent sequelize from adding a specific association method?

like image 809
Arwed Mett Avatar asked Nov 08 '22 10:11

Arwed Mett


1 Answers

  1. Is there a way to create a custom association method, if not can I at least define a validation method?

As i know there is no way to create custom associated method. All customization you can achieve through scope field. For example:

  models.User.belongsToMany(
    models.List,
    {
      through: {
        model: models.UserList,
        scope: {
          owner: true,
        },
      },
      as: {
        singular: 'OwnedList',
        plural: 'OwnedLists',
      },
    });

So when I call user.addOwnedList(...) property owner on UserList will be true by default. Same for 1:m associations, some fields may be set through scope. Also you can have different associatin scopes and divide them by as field. For example:

  models.User.belongsToMany(
    models.List,
    {
      through: models.UserList,
      as: {
        singular: 'List',
        plural: 'Lists',
      },
    });

So to find all List will use user.getLists(...) and to share list with other user will use "user2.addList(...)" so property owner will be false. And to get only owned lists will use user.getOwnedLists(...) result SQL will be like WHERE "owner"=true by defaut.

  1. Can I prevent sequelize from adding a specific association method?

You can't prevent creation of method, but you can delete it immediately after association. For example:

user.associate = function (models) {
  models.User.belongsToMany(
    models.List,
    {
      through: models.UserList,
      as: {
        singular: 'List',
        plural: 'Lists',
      },
    });

  models.User.belongsToMany(
    models.List,
    {
      through: {
        model: models.UserList,
        scope: {
          owner: true,
        },
      },
      as: {
        singular: 'OwnedList',
        plural: 'OwnedLists',
      },
    });

  /**
   * Deleting method createList to prevent list creation
   * without owner
   * List must be created using user.createOwnedList
   */
  delete user.prototype.createList;
};

So when someone calls method user.createList it will result in undefined is not a function error. It's not perfect solution but at least it adds more security and data consistency without complex constraints.

like image 61
Денис Богатырев Avatar answered Nov 14 '22 21:11

Денис Богатырев