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

Commit 3168d543 by LoneWolfPR Committed by Jan Aagaard Meier

v3: sourceKey feature for hasMany doesn't work if where clause specified in include (#7141) (#7147)

* Initial Commit

* Stops test from removing test/integration/assets/es6project.js

* Fixes impromper syntax when specifying the use of association.sourceIdentifier or left.primaryKeyAttribute for attrLeft. Also includes integration test.

* Updates changelog.

* Adds link to issue in changelog entry.

* Added 'Future' header to changelog entry

* Removed changelog update as requested.

* Updates changelog. Fixes query-generator to properly build queries from hasMany even with an include while respecting a specified sourceKey. Adds an integration test.

* Added back removed whitespace per request.

* Updates test in include altered field name in source key. Fixes were then made to address the test breaking. All tests pass now.

* Adds back removed whitespace.
1 parent 2110276a
# Future # Future
- [FIXED] `sourceKey` FOR `hasMany` now also works if a `where` was specified in an `include` [#7141](https://github.com/sequelize/sequelize/issues/7141)
- [CHANGED] Updated deprecated `node-uuid` package to `uuid` [#7148](https://github.com/sequelize/sequelize/pull/7148) - [CHANGED] Updated deprecated `node-uuid` package to `uuid` [#7148](https://github.com/sequelize/sequelize/pull/7148)
# 3.30.0 # 3.30.0
......
...@@ -91,6 +91,11 @@ var HasMany = function(source, target, options) { ...@@ -91,6 +91,11 @@ var HasMany = function(source, target, options) {
this.sourceKeyField = this.sourceKey; this.sourceKeyField = this.sourceKey;
} }
if (this.source.fieldRawAttributesMap[this.sourceKey]) {
this.sourceKeyAttribute = this.source.fieldRawAttributesMap[this.sourceKey].fieldName;
} else {
this.sourceKeyAttribute = this.source.primaryKeyAttribute;
}
this.sourceIdentifier = this.sourceKey; this.sourceIdentifier = this.sourceKey;
this.associationAccessor = this.as; this.associationAccessor = this.as;
...@@ -211,7 +216,7 @@ HasMany.prototype.injectAttributes = function() { ...@@ -211,7 +216,7 @@ HasMany.prototype.injectAttributes = function() {
var newAttributes = {}; var newAttributes = {};
var constraintOptions = _.clone(this.options); // Create a new options object for use with addForeignKeyConstraints, to avoid polluting this.options in case it is later used for a n:m var constraintOptions = _.clone(this.options); // Create a new options object for use with addForeignKeyConstraints, to avoid polluting this.options in case it is later used for a n:m
newAttributes[this.foreignKey] = _.defaults({}, this.foreignKeyAttribute, { newAttributes[this.foreignKey] = _.defaults({}, this.foreignKeyAttribute, {
type: this.options.keyType || this.source.rawAttributes[this.sourceKey].type, type: this.options.keyType || this.source.rawAttributes[this.sourceKeyAttribute].type,
allowNull : true allowNull : true
}); });
......
...@@ -1336,7 +1336,7 @@ var QueryGenerator = { ...@@ -1336,7 +1336,7 @@ var QueryGenerator = {
, subQueryWhere; , subQueryWhere;
associationWhere[association.identifierField] = { associationWhere[association.identifierField] = {
$raw: self.quoteTable(parentTable) + '.' + self.quoteIdentifier(association.source.primaryKeyField) $raw: self.quoteTable(parentTable) + '.' + self.quoteIdentifier(association.sourceKeyField || association.source.primaryKeyField)
}; };
if (!options.where) options.where = {}; if (!options.where) options.where = {};
...@@ -1707,10 +1707,10 @@ var QueryGenerator = { ...@@ -1707,10 +1707,10 @@ var QueryGenerator = {
, asLeft , asLeft
, attrLeft = association instanceof BelongsTo ? , attrLeft = association instanceof BelongsTo ?
association.identifier : association.identifier :
left.primaryKeyAttribute association.sourceKeyAttribute || left.primaryKeyAttribute
, fieldLeft = association instanceof BelongsTo ? , fieldLeft = association instanceof BelongsTo ?
association.identifierField : association.identifierField :
left.rawAttributes[association.sourceIdentifier || left.primaryKeyAttribute].field left.rawAttributes[association.sourceKeyAttribute || left.primaryKeyAttribute].field
/* Attributes for the right side */ /* Attributes for the right side */
, right = include.model , right = include.model
...@@ -1770,7 +1770,7 @@ var QueryGenerator = { ...@@ -1770,7 +1770,7 @@ var QueryGenerator = {
} }
} }
} }
return joinType + this.quoteTable(tableRight, asRight) + ' ON ' + joinOn; return joinType + this.quoteTable(tableRight, asRight) + ' ON ' + joinOn;
}, },
......
...@@ -1285,4 +1285,46 @@ describe(Support.getTestDialectTeaser('HasMany'), function() { ...@@ -1285,4 +1285,46 @@ describe(Support.getTestDialectTeaser('HasMany'), function() {
}); });
describe('sourceKey with where clause in include', function() {
beforeEach(function() {
var User = this.sequelize.define('User',
{ username: Sequelize.STRING, email: { type: Sequelize.STRING, field: 'mail'} },
{ indexes: [ {fields: ['mail'], unique: true} ] }
);
var Task = this.sequelize.define('Task',
{ title: Sequelize.STRING, userEmail: Sequelize.STRING, taskStatus: Sequelize.STRING });
User.hasMany(Task, {foreignKey: 'userEmail', sourceKey: 'mail'});
this.User = User;
this.Task = Task;
return this.sequelize.sync({ force: true });
});
it('should use the specified sourceKey instead of the primary key', function() {
var User = this.User, Task = this.Task;
return User.create({ username: 'John', email: 'john@example.com'}).then(function() {
return Task.bulkCreate([
{ title: 'Active Task', userEmail: 'john@example.com', taskStatus: 'Active'},
{ title: 'Inactive Task', userEmail: 'john@example.com', taskStatus: 'Inactive'}]).then(function() {
return User.find({
include: [
{
model: Task,
where: {taskStatus: 'Active'}
}
],
where: { username: 'John' }
}).then(function(user) {
expect(user).to.be.ok;
expect(user.Tasks.length).to.equal(1);
expect(user.Tasks[0].title).to.equal('Active Task');
});
});
});
});
});
}); });
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!