Sequelize ownToMany игнорирует дополнительные атрибуты в таблице соединений - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть две модели: Артикул и ОписаниеФрагмент в BelongsToMany ассоциация через таблицу соединений Описания , которые в свою очередь BelongsTo другая модель Категория , а также имеет атрибут «последовательность», определяемый следующим образом:

Артикул Модель:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Article = sequelize.define('Article', {
    uid: {
      type: DataTypes.INTEGER,
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      field: 'uid'
    },
    articleNumber: {
      type: DataTypes.INTEGER(8),
      allowNull: false,
      field: 'article_number',
      unique: true
    },
  }, {
    underscored: true,
  });
  Article.associate = function (models) {
    Article.belongsToMany(models.DescriptionFragment, {
      through: 'Descriptions',
      as: 'articleWithDescriptionFragment',
      otherKey: {
        name: 'descriptionFragmentId',
        field: 'description_fragment_id'
      },
      foreignKey: {
        name: 'articleId',
        field: 'article_id'
      },
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE'
    });
  };
  return Article;
};

ОписаниеФрагмент модель:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const DescriptionFragment = sequelize.define('DescriptionFragment', {
    uid: {
      type: DataTypes.INTEGER,
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      field: 'uid'
    }
  }, {
    charset: 'utf8',
    dialectOptions: {
      collate: 'utf8_general_ci'
    },
    timestamps: true,
    paranoid: true,
    underscored: true,
  });
  DescriptionFragment.associate = function (models) {
    DescriptionFragment.belongsToMany(models.Article, {
      through: 'Descriptions',
      as: 'descriptionFragmentForArticle',
      foreignKey: {
        name: 'descriptionFragmentId',
        field: 'description_fragment_id'
      },
      otherKey: {
        name: 'articleId',
        field: 'article_id'
      },
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE'
    });
  };
  return DescriptionFragment;
};

Описание модель:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Description = sequelize.define('Description', {
    sequence: {
      type: DataTypes.INTEGER,
      allowNull: true
    }
  }, {
    charset: 'utf8',
    dialectOptions: {
      collate: 'utf8_general_ci'
    },
    timestamps: true,
    paranoid: true,
    underscored: true,
  });
  Description.associate = function (models) {
    Description.belongsTo(models.Category, {
      as: 'categoryDescription',
      foreignKey: {
        name: 'categoryId',
        field: 'category_id'
      },
      targetKey: 'uid',
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE'
    });
  };
  return Description;
};

Категория модель:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Category = sequelize.define('Category', {
    uid: {
      type: DataTypes.INTEGER,
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      field: 'uid'
    }
  }, {
    charset: 'utf8',
    dialectOptions: {
      collate: 'utf8_general_ci'
    },
    timestamps: true,
    paranoid: true,
    underscored: true,
  });
  Category.associate = function (models) {
    Category.hasMany(models.Description, {
      foreignKey: {
        name: 'categoryId',
        field: 'category_id'
      },
      sourceKey: 'uid',
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE'
    });
  };
  return Category;
};

Моя проблема возникает, когда я пытаюсь связать DescriptionFragment с Article .Я использую следующий код:

let addedArticle = await Article.create(newArticle);

addedArticle.addArticleWithDescriptionFragment(descFrag, {
    through: {
      categoryId: catId,
      sequence: index
    }
  });

, где descFrag является экземпляром модели DescriptionFragment и catId и index являются целыми числами.

Когда этот код выполняется, sequelize создает Article instance AddedArticle , но затем при попытке связать его с DescriptionFragment это просто игнорирует то, что находится в опции от до .Сгенерированный SQL, например:

Executing (default): INSERT INTO "devdb"."Descriptions" ("created_at","updated_at","article_id","description_fragment_id") VALUES ('2019-02-07 15:11:15.376 +00:00','2019-02-07 15:11:15.376 +00:00',95,5);

Насколько я мог найти в документации , синтаксис, который я использую, является правильным, и связь создается в описания таблица, только с null для sequence и category_id .

Я использую sequelize v4.38.1, а база данных - Postgres.

Я не могу определить, где находится ошибка, и все подобные проблемы, которые я обнаружил до сих пор, просто использовали в sequelize v4 старый синтаксис для v3.

Любое понимание будет оценено, спасибо!


ОБНОВЛЕНИЕ

Сейчас я использую следующий обходной путь:

await addedArticle.addArticleWithDescriptionFragment(descFrag);
let newDesc = await models.Description.find({
  where: { articleId: addedArticle.uid, descriptionFragmentId: descFrag.uid }
});
await newDesc.update({ categoryId: catId, sequence: index });

, который правильно устанавливает нужные столбцы:

Executing (default): UPDATE "techred_dev"."Descriptions" SET "category_id"=2,"sequence"=0,"updated_at"='2019-02-08 09:21:20.216 +00:00' WHERE "article_id" = 104 AND "description_fragment_id" = 6

Конечно, чтобы это работало, мне пришлось обновить Description модель, явно добавив столбцы articleId и descriptionFragmentId :

articleId: {
  type: DataTypes.INTEGER,
  onDelete: 'CASCADE',
  onUpdate: 'CASCADE',
  references: {
    model: 'Articles',
    key: 'uid'
  },
  primaryKey: true,
  field: 'article_id'
},
descriptionFragmentId: {
  type: DataTypes.INTEGER,
  onDelete: 'CASCADE',
  onUpdate: 'CASCADE',
  references: {
    model: 'DescriptionFragments',
    key: 'uid'
  },
  primaryKey: true,
  field: 'description_fragment_id'
},

Тем не менее, опция 'through' в методе 'add' не работает, и я понятия не имею, почему.

...