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

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
- [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)
# 3.30.0
......
......@@ -91,6 +91,11 @@ var HasMany = function(source, target, options) {
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.associationAccessor = this.as;
......@@ -211,7 +216,7 @@ HasMany.prototype.injectAttributes = function() {
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
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
});
......
......@@ -1336,7 +1336,7 @@ var QueryGenerator = {
, subQueryWhere;
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 = {};
......@@ -1707,10 +1707,10 @@ var QueryGenerator = {
, asLeft
, attrLeft = association instanceof BelongsTo ?
association.identifier :
left.primaryKeyAttribute
association.sourceKeyAttribute || left.primaryKeyAttribute
, fieldLeft = association instanceof BelongsTo ?
association.identifierField :
left.rawAttributes[association.sourceIdentifier || left.primaryKeyAttribute].field
left.rawAttributes[association.sourceKeyAttribute || left.primaryKeyAttribute].field
/* Attributes for the right side */
, right = include.model
......
......@@ -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!