создать / обновить ассоциацию «многие ко многим» в Node.js sequelize и PostgreSQL - PullRequest
0 голосов
/ 02 марта 2020

Я просто создаю или обновляю таблицу, имеющую связь «многие ко многим» с другой таблицей, например, здесь: Company <-> Industry <-> CompanyIndustryRelation.

Industry. js

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Industry = sequelize.define('Industry', {
    industry_name: DataTypes.STRING,
  }, {
    timestamps: false,
    underscored: true,
    tableName: 'industry',
  });
  Industry.associate = function(models) {
    Industry.belongsToMany(models.Company, {
      through: 'company_industry_relation', foreignkey: 'industry_id'
    });
  };
  return Industry;
};

Company. js

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Company = sequelize.define('Company', {
    company_name: DataTypes.STRING,
  }, {
    timestamps: false,
    underscored: true,
    tableName: 'company',
  });
  Company.associate = function(models) {
    Company.belongsToMany(models.Industry, {
      through: 'company_industry_relation', foreignKey: 'company_id'
    });
  };
  return Company;
};

CompanyIndustryRelation. js

'use strict';
module.exports = (sequelize, DataTypes) => {
  const CompanyIndustryRelation = sequelize.define('CompanyIndustryRelation', {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
    },
  }, {
    timestamps: false,
    underscored: true,
    tableName: 'company_industry_relation',
  });
  return CompanyIndustryRelation;
};

В настоящее время таблица отрасли уже построена, как показано ниже. enter image description here

Промышленность отраслевых массивов = [{label: 'Accounting'}, {label: 'Computer Science'}]

CompanyName: 'ApolloIT'

Я хочу создать новую запись о компании с указанным отраслевым массивом и companyName.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Я нашел простой способ создания / обновления записей с ассоциациями.

industries: [ 
 { value: 'Gaming', label: 'Gaming' },
 { value: 'Computer Science', label: 'Computer Science' } 
]

const company = await Company.create({
   company_name: companyName,
});

const industry = await Industry.findAll({
   where: { industry_name: { [Op.in]: _.map(industries, o => o.label) } }
});
await company.addIndustry(industry);

Пожалуйста, обратитесь сюда. https://sequelize.org/master/manual/advanced-many-to-many.html

0 голосов
/ 02 марта 2020

Хорошо. Насколько я понимаю, вы не правильно делаете определение модели. В sequelize вы создаете модель для связи с таблицей базы данных, обычно эта модель должна совпадать с таблицей базы данных.

Для промышленности. js, вы просто определяете столбец industry_name, забывая ID . То же самое касается компании. js. Если sequeliaze не знает первичный ключ ... он не будет работать хорошо.

В случае CompanyIndustryRelation. js, как правило, вам не нужен id , так как Первичным ключом (как правило) является идентификатор связанных таблиц. В этом случае это должно быть industry_id и company_id. Опять же, в CompanyIndustryRelation. js таких полей нет.

При использовании отношения n to n сначала необходимо создать главные таблицы. Если у вас есть:

company ---> CompanyIndustryRelation <--- Industry </p>

Затем сначала необходимо создать company и industry, а затем CompanyIndustryRelation. * 1021. *

В sequelize вы можете сделать (для создания):

sequelize.transaction((t) => {// to make a rollback in case something goes wrong

    return Company.create(data_company, { transaction: t }).then((new_company) => {

        return Industry.create(data_industry, { transaction: t }).then((new_industry) => {

            //here goes the created ids, asuming your using autoincrement to create ids
            var data_relation = {industry_id: new_industry.id,company_id: new_company.id};
            return CompanyIndustryRelation.create(data_relation, { transaction: t }).then(()=>{

                return;// Everything OK you could return something here

// when there is an error, you have to throw it for the rollback to work
            }).catch(err => {throw err;});

        }).catch(err => {throw err;});

    }).catch(err => {throw err;});

}).catch(err => {
    // process error, then rollback
});

Для обновления то же самое, если вы хотите обновить в каскаде, это хорошая практика использовать транзакции в случае чего-то в середине идет не так.

Существуют и другие способы использования каскадных обновлений или создания, но все лучше, если вы используете транзакций

...