首页 > 解决方案 > Feathers-Sequelize : belongsToMany 或 belongsTo... 创建关联

问题描述

使用羽毛+续集(newbee)我想为标签模型建立多对多关系,其中标签可以有很多父母和很多孩子。

    tags.belongsToMany(tags, {
      as: 'parents',
      through: tags_tags,
      foreignKey: 'parentId',
      otherKey: 'id',
      onDelete: 'RESTRICT',
      onUpdate: 'CASCADE',
    });

    tags.belongsToMany(tags, {
      as: 'children',
      through: tags_tags,
      foreignKey: 'id',
      otherKey: 'parentId',
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE',
    });

模型似乎很好,数据库也很好。

现在,我正在研究如何从羽毛服务中添加关系。变得非常沮丧,因为这应该很简单,但我似乎找不到任何可以帮助我的东西。我错过了一些明显的东西吗?

app.services.tags
  .create({
    name: 'siteRoot',
  })
  .then(siteRoot => {
    // something like siteRoot.addChild() ?
    // app.services.tags.Model has .children
    // but how can I use it ?
  })

在模型/tags.model.ts

// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
import { Sequelize, DataTypes, Op } from 'sequelize';
import { Application } from '../declarations';

export default function (app: Application) {
  const sequelizeClient: Sequelize = app.get('sequelizeClient');
  const tags = sequelizeClient.define(
    'tags',
    {
      id: {
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true,
      },
      deleted: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: false,
      },
      name: {
        type: DataTypes.STRING,
        allowNull: false,
      },
    },
    {
      hooks: {
        beforeCount(options: any) {
          options.raw = true;
        },
      },
      // timestamps: false,
      // tableName: 'tag',
      // underscored: true,
      indexes: [
        {
          fields: ['name'],
        },
    }
  );

  // eslint-disable-next-line no-unused-vars
  (tags as any).associate = function (models: any) {
    // Define associations here
    // See http://docs.sequelizejs.com/en/latest/docs/associations/

    const { tags } = models;

    tags.belongsTo(tags, {
      foreignKey: 'siteBaseTagId',
      as: 'siteBaseTag',
      onDelete: 'RESTRICT',
      onUpdate: 'CASCADE',
    });

    tags.hasMany(tags, {
      foreignKey: 'siteBaseTagId',
      as: 'siteTags',
    });
  };

  return tags;
}

并在模型/标签-标签.model.ts


// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
import { Sequelize, DataTypes } from 'sequelize';
import { Application } from '../declarations';

export default function (app: Application) {
  const sequelizeClient: Sequelize = app.get('sequelizeClient');
  const tagsTags = sequelizeClient.define(
    'tags_tags',
    {
      id: {
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
      },
      parentId: {
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
      },
      template: {
        type: DataTypes.STRING,
        allowNull: true,
      },
      url: {
        type: DataTypes.STRING,
        allowNull: true,
      },
    },
    {
      hooks: {
        beforeCount(options: any) {
          options.raw = true;
        },
      },
      timestamps: false,
    }
  );

  // eslint-disable-next-line no-unused-vars
  (tagsTags as any).associate = function (models: any) {
    // Define associations here
    // See http://docs.sequelizejs.com/en/latest/docs/associations/

    const { tags, tags_tags } = models;

    tags.belongsToMany(tags, {
      as: 'parents',
      through: tags_tags,
      foreignKey: 'parentId',
      otherKey: 'id',
      onDelete: 'RESTRICT',
      onUpdate: 'CASCADE',
    });

    tags.belongsToMany(tags, {
      as: 'children',
      through: tags_tags,
      foreignKey: 'id',
      otherKey: 'parentId',
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE',
    });

    tags_tags.belongsTo(tags, {
      foreignKey: 'parentId',
    });
    tags.hasMany(tags_tags, {
      foreignKey: 'parentId',
    });

    tags_tags.belongsTo(tags, {
      foreignKey: 'id',
    });
    tags.hasMany(tags_tags, {
      foreignKey: 'id',
    });
  };

  return tagsTags;
}

标签: sequelize.jsfeathersjs

解决方案


belongsToMany是羽毛方面最难处理的协会之一。限制绝对不是feathers最后,而是如何sequelize处理它们。

我对你的问题有点困惑。如果您能准确说明需要帮助的地方,则愿意提供帮助。

旁注:也许你应该重命名你的模型有点不同。tags|| tags_tags似乎彼此接近,并且在某些时候会//可能会混淆。平均时间想向您指出这个已经活跃了一段时间的线程,因为每个人都在以belongsToMany不同的方式处理这种关系。希望你能从中得到一些指点。 https://github.com/feathersjs/feathers/issues/852#issuecomment-406413342

如果你M:N只需要那么我会这样做:

// tag model
tag.associate = models => {
  tag.belongsToMany(models.tag_tag, {
    through: 'parent_child_table', // name this table to your liking.
    foreignKey: 'tag_id'
  });
};

// tag_tag model
tag_tag.associate = models => {
  tag_tag.belongsToMany(models.tag, {
    through: 'parent_child_table', // table name MUST be the same as above
    foreignKey: 'tag_tag_id'
  });
};

以上将创建另一个表parent_child_table,您将在其中跟踪您的关联。您必须创建一个单独的服务才能CRUD在此表上执行。这应该让你开始。


推荐阅读