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

Commit 9d08b583 by Mick Hansen

fix(belongsTo): now correctly creates foreign key constraints when targetyKey is…

… a unique key and table has a primary key, closes #4455
1 parent cbeaf4b7
......@@ -4,6 +4,7 @@
- [FIXED] Reload doesn't synchronize a null include [#4353](https://github.com/sequelize/sequelize/issues/4353)
- [FIXED] commit/rollback multiple times on same transaction [#4491](https://github.com/sequelize/sequelize/issues/4491)
- [FIXED] memory leak / options mangle for scopes with include [#4470](https://github.com/sequelize/sequelize/issues/4470)
- [FIXED] custom `targetKey` for belongsTo on a target with a primary key will now correctly create foreign key constraints [#4455](https://github.com/sequelize/sequelize/issues/4455)
# 3.8.0
- [ADDED] `version` on `Sequelize` returning the current npm/package.json version [#4459](https://github.com/sequelize/sequelize/pull/4459)
......
......@@ -61,6 +61,8 @@ var BelongsTo = function(source, target, options) {
}
this.targetKey = this.options.targetKey || this.target.primaryKeyAttribute;
this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
this.targetIdentifier = this.targetKey;
this.associationAccessor = this.as;
this.options.useHooks = options.useHooks;
......@@ -115,7 +117,7 @@ BelongsTo.prototype.injectAttributes = function() {
this.options.onUpdate = this.options.onUpdate || 'CASCADE';
}
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.target, this.source, this.options);
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.target, this.source, this.options, this.targetKeyField);
Utils.mergeDefaults(this.source.rawAttributes, newAttributes);
this.identifierField = this.source.rawAttributes[this.foreignKey].field || this.foreignKey;
......
......@@ -12,7 +12,7 @@ function checkNamingCollision (association) {
}
}
function addForeignKeyConstraints (newAttribute, source, target, options) {
function addForeignKeyConstraints (newAttribute, source, target, options, key) {
// FK constraints are opt-in: users must either set `foreignKeyConstraints`
// on the association, or request an `onDelete` or `onUpdate` behaviour
......@@ -20,8 +20,8 @@ function addForeignKeyConstraints (newAttribute, source, target, options) {
// Find primary keys: composite keys not supported with this approach
var primaryKeys = Utils._.chain(source.rawAttributes).keys()
.filter(function(key) { return source.rawAttributes[key].primaryKey; })
.map(function(key) { return source.rawAttributes[key].field || key; }).value();
.filter(function($key) { return source.rawAttributes[$key].primaryKey; })
.map(function($key) { return source.rawAttributes[$key].field || $key; }).value();
if (primaryKeys.length === 1) {
if (!!source.options.schema) {
......@@ -38,7 +38,7 @@ function addForeignKeyConstraints (newAttribute, source, target, options) {
newAttribute.references = { model: source.tableName };
}
newAttribute.references.key = primaryKeys[0];
newAttribute.references.key = key || primaryKeys[0];
newAttribute.onDelete = options.onDelete;
newAttribute.onUpdate = options.onUpdate;
}
......
......@@ -616,9 +616,10 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
});
});
it('should support a non-primary key as the association column', function() {
it('should support a non-primary key as the association column on a target without a primary key', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING });
User.removeAttribute('id');
Task.belongsTo(User, { foreignKey: 'user_name', targetKey: 'username'});
......@@ -637,6 +638,35 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
});
});
it('should support a non-primary unique key as the association column', function() {
var User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
field: 'user_name',
unique: true
}
})
, Task = this.sequelize.define('Task', {
title: DataTypes.STRING
});
Task.belongsTo(User, { foreignKey: 'user_name', targetKey: 'username'});
return this.sequelize.sync({ force: true }).then(function() {
return User.create({ username: 'bob' }).then(function(newUser) {
return Task.create({ title: 'some task' }).then(function(newTask) {
return newTask.setUser(newUser).then(function() {
return Task.findOne({title: 'some task'}).then(function (foundTask) {
return foundTask.getUser().then(function (foundUser) {
expect(foundUser.username).to.equal('bob');
});
});
});
});
});
});
});
it('should support a non-primary key as the association column with a field option', function() {
var User = this.sequelize.define('User', {
username: {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!