Есть ли способ остановить сиквелизацию sync() от добавления определенных внешних ключей?

Вот суть проблемы.

У меня есть таблица "Коробки". Существует несколько таблиц элементов, которые можно связать с коробкой («Виджеты», «Догики», «Штучки»).

У меня есть реляционная таблица "ItemsInBox" с BoxId, ItemId, itemType.

В своих моделях я создаю ассоциации (belongsToMany, hasMany), используя «ItemsInBox» в качестве «сквозной» таблицы, но нет фактических внешних ключей, связанных с различными таблицами элементов, поскольку это может вызвать конфликты внешних ключей. Все это работает нормально.

Проблема в том, что когда я пишу тесты для моделей, я использую sequenceize.sync() для создания таблиц. Sync() автоматически добавляет внешние ключи для всех ассоциаций.

Я не могу использовать свойство «ссылки» в определениях модели для создания ассоциаций, потому что таблица «Коробки» должна иметь возможность ссылаться на 3 разные таблицы, но, насколько я могу судить, свойство ссылок не может быть массивом.

Есть ли способ сказать, чтобы sequenceize.sync() пропустил добавление внешних ключей для определенных ассоциаций?

Примечание. В настоящее время используется sequenceize v3, но работа над обновлением до v5.


person bmelton    schedule 10.06.2020    source источник


Ответы (1)


Разобрался как это сделать.

В вашем сценарии инициализации вы должны перебрать все модели и выполнить [model].associate(models).

Что-то вроде

const tableNames = Object.keys(models)
    for (let modelName of tableNames) {
        let model = models[modelName]
        if (typeof model.associate === 'function') model.associate(db)
    }

В ваших моделях у вас есть ассоциированная функция.

in v3/v4

classMethods: {
    associate: function (models) {
      ...
    }
}  

in v5

[model].associate(){
}

или если вы используете определения классов вместо определения, у вас есть ассоциированное свойство.

Создайте вторую функцию для создания ассоциаций без внешнего ключа.

in v3/v4

classMethods: {
    associate: function (models) {
      ...
    },
    nfkAssociate: function (models) {
      [model].belongsTo(...)
    }
}  

in v5

[model].nfkAssociate = function (models) {
    [model].belongsTo(...)
}

Затем в вашем сценарии инициализации

const tableNames = Object.keys(models)
for (let modelName of tableNames) {
    let model = models[modelName]
    if (typeof model.associate === 'function'){ 
       model.associate(db)
    }
}
db.doNFKAssociations = function () {
    for (let modelName of tableNames) {
        const model = db[modelName]
        if (model.nfkAssociate) {
            model.nfkAssociate(db)
        }
    }
}
if (!config.delayNFKAssociations) {
    db.doNFKAssociations()
}

По умолчанию вы сразу же запускаете как Associate(), так и nfkAssociate(). Если вы находитесь в такой ситуации, как запуск автоматических тестов, вы добавляете в конфигурацию инициализации дополнительное свойство «delayNFKAssociations», которое предотвратит выполнение вторичных ассоциаций.

Где вы используете sync():

await sqldb.sequelize.sync({force: true }).then(() => {
  // create all of the associations that shouldn't have foreign keys associated
  sqldb.doNFKAssociations()
})

Теперь вы создаете свои ассоциации после запуска метода sync() и не получаете нежелательных внешних ключей.

person bmelton    schedule 11.06.2020