Feathers-Sequelize: принадлежат многим или принадлежат ... создать ассоциацию - PullRequest
0 голосов
/ 22 апреля 2020

Использование перьев + продолжение (newbee) Я хочу построить отношение «многие ко многим» для модели Tag, где у тега может быть много родителей и много детей.

    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 ?
  })

в models / 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;
}

и в models / tags-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;
}

1 Ответ

0 голосов
/ 30 апреля 2020

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 на этой таблице. Это должно начать вас.

...