不要怂,就是干,撸起袖子干!

Commit 461c9242 by Sushant Committed by GitHub

fix(associations): ensure correct schema on all generated attributes (#12258)

1 parent 4d75caf4
......@@ -21,19 +21,11 @@ function addForeignKeyConstraints(newAttribute, source, target, options, key) {
.map(primaryKeyAttribute => source.rawAttributes[primaryKeyAttribute].field || primaryKeyAttribute);
if (primaryKeys.length === 1 || !primaryKeys.includes(key)) {
if (source._schema) {
newAttribute.references = {
model: source.sequelize.getQueryInterface().queryGenerator.addSchema({
tableName: source.tableName,
_schema: source._schema,
_schemaDelimiter: source._schemaDelimiter
})
model: source.getTableName(),
key: key || primaryKeys[0]
};
} else {
newAttribute.references = { model: source.tableName };
}
newAttribute.references.key = key || primaryKeys[0];
newAttribute.onDelete = options.onDelete;
newAttribute.onUpdate = options.onUpdate;
}
......
......@@ -648,7 +648,6 @@ class MSSQLQueryGenerator extends AbstractQueryGenerator {
attribute = attributes[key];
if (attribute.references) {
if (existingConstraints.includes(attribute.references.model.toString())) {
// no cascading constraints to a table more than once
attribute.onDelete = '';
......
......@@ -411,7 +411,6 @@ class MySQLQueryGenerator extends AbstractQueryGenerator {
}
if (attribute.references) {
if (options && options.context === 'addColumn' && options.foreignKey) {
const attrName = this.quoteIdentifier(options.foreignKey);
const fkName = this.quoteIdentifier(`${options.tableName}_${attrName}_foreign_idx`);
......
......@@ -48,9 +48,12 @@ exports.isPrimitive = isPrimitive;
// Same concept as _.merge, but don't overwrite properties that have already been assigned
function mergeDefaults(a, b) {
return _.mergeWith(a, b, objectValue => {
return _.mergeWith(a, b, (objectValue, sourceValue) => {
// If it's an object, let _ handle it this time, we will be called again for each property
if (!_.isPlainObject(objectValue) && objectValue !== undefined) {
if (_.isFunction(objectValue) && _.isNative(objectValue)) {
return sourceValue || objectValue;
}
return objectValue;
}
});
......
......@@ -2,6 +2,7 @@
const chai = require('chai'),
expect = chai.expect,
sinon = require('sinon'),
Support = require('../../support'),
Sequelize = Support.Sequelize,
Op = Sequelize.Op,
......@@ -130,6 +131,57 @@ if (dialect.match(/^mssql/)) {
expect(separateUsers[1].get('LoginLogs')).to.have.length(1);
});
it('allow referencing FK to different tables in a schema with onDelete, #10125', async function() {
const Child = this.sequelize.define(
'Child',
{},
{
timestamps: false,
freezeTableName: true,
schema: 'a'
}
);
const Toys = this.sequelize.define(
'Toys',
{},
{
timestamps: false,
freezeTableName: true,
schema: 'a'
}
);
const Parent = this.sequelize.define(
'Parent',
{},
{
timestamps: false,
freezeTableName: true,
schema: 'a'
}
);
Child.hasOne(Toys, {
onDelete: 'CASCADE'
});
Parent.hasOne(Toys, {
onDelete: 'CASCADE'
});
const spy = sinon.spy();
await this.sequelize.queryInterface.createSchema('a');
await this.sequelize.sync({
force: true,
logging: spy
});
expect(spy).to.have.been.called;
const log = spy.args.find(arg => arg[0].includes('IF OBJECT_ID(\'[a].[Toys]\', \'U\') IS NULL CREATE TABLE'))[0];
expect(log.match(/ON DELETE CASCADE/g).length).to.equal(2);
});
it('sets the varchar(max) length correctly on describeTable', async function() {
const Users = this.sequelize.define('_Users', {
username: Sequelize.STRING('MAX')
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!