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

Commit bda2ed15 by Mick Hansen

fix(include): fix support for N:M includes and primary keys with fields other than attribute name

1 parent 8731f222
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
- [BUG] Fixed support for 2 x belongsToMany without foreignKey defined and association getter/adder [#3185](https://github.com/sequelize/sequelize/issues/3185) - [BUG] Fixed support for 2 x belongsToMany without foreignKey defined and association getter/adder [#3185](https://github.com/sequelize/sequelize/issues/3185)
- [BUG] No longer throws on `Model.hasHook()` if no hooks are defiend [#3181](https://github.com/sequelize/sequelize/issues/3181) - [BUG] No longer throws on `Model.hasHook()` if no hooks are defiend [#3181](https://github.com/sequelize/sequelize/issues/3181)
- [BUG] Fixed issue with `{$and: []}` - [BUG] Fixed issue with `{$and: []}`
- [BUG] Fixed issue with N:M relations with primary keys with field defined
# 2.0.3 # 2.0.3
- [BUG] Support for plain strings, ints and bools on JSON insert - [BUG] Support for plain strings, ints and bools on JSON insert
......
...@@ -989,9 +989,23 @@ module.exports = (function() { ...@@ -989,9 +989,23 @@ module.exports = (function() {
mainAttributes = mainAttributes.concat(throughAttributes); mainAttributes = mainAttributes.concat(throughAttributes);
} }
// Figure out if we need to use field or attribute
if (!subQuery) {
attrSource = association.source.rawAttributes[primaryKeysSource[0]].field;
}
if (subQuery && !include.subQuery && !include.parent.subQuery && include.parent.model !== mainModel) {
attrSource = association.source.rawAttributes[primaryKeysSource[0]].field;
}
// Filter statement for left side of through // Filter statement for left side of through
// Used by both join and subquery where // Used by both join and subquery where
// If parent include was in a subquery need to join on the aliased attribute
if (subQuery && !include.subQuery && include.parent.subQuery) {
sourceJoinOn = self.quoteIdentifier(tableSource + '.' + attrSource) + ' = ';
} else {
sourceJoinOn = self.quoteTable(tableSource) + '.' + self.quoteIdentifier(attrSource) + ' = '; sourceJoinOn = self.quoteTable(tableSource) + '.' + self.quoteIdentifier(attrSource) + ' = ';
}
sourceJoinOn += self.quoteIdentifier(throughAs) + '.' + self.quoteIdentifier(identSource); sourceJoinOn += self.quoteIdentifier(throughAs) + '.' + self.quoteIdentifier(identSource);
// Filter statement for right side of through // Filter statement for right side of through
...@@ -1128,7 +1142,8 @@ module.exports = (function() { ...@@ -1128,7 +1142,8 @@ module.exports = (function() {
, subQueryJoinOn; , subQueryJoinOn;
// Filter statement // Filter statement
// Used by both join and subquery where // Used by both join and
where
if (subQuery && !include.subQuery && include.parent.subQuery && (include.hasParentRequired || include.hasParentWhere || include.parent.hasIncludeRequired || include.parent.hasIncludeWhere)) { if (subQuery && !include.subQuery && include.parent.subQuery && (include.hasParentRequired || include.hasParentWhere || include.parent.hasIncludeRequired || include.parent.hasIncludeWhere)) {
joinOn = self.quoteIdentifier(tableLeft + '.' + attrLeft); joinOn = self.quoteIdentifier(tableLeft + '.' + attrLeft);
} else { } else {
......
...@@ -1932,7 +1932,7 @@ module.exports = (function() { ...@@ -1932,7 +1932,7 @@ module.exports = (function() {
var include = includes[index] = validateIncludedElement.call(this, includes[index], tableNames); var include = includes[index] = validateIncludedElement.call(this, includes[index], tableNames);
include.parent = options; include.parent = options;
// associations that are required or have a required child as is not a ?:M association are candidates for the subquery // associations that are required or have a required child and is not a ?:M association are candidates for the subquery
include.subQuery = !include.association.isMultiAssociation && (include.hasIncludeRequired || include.required); include.subQuery = !include.association.isMultiAssociation && (include.hasIncludeRequired || include.required);
include.hasParentWhere = options.hasParentWhere || !!options.where; include.hasParentWhere = options.hasParentWhere || !!options.where;
include.hasParentRequired = options.hasParentRequired || !!options.required; include.hasParentRequired = options.hasParentRequired || !!options.required;
......
...@@ -311,14 +311,106 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() { ...@@ -311,14 +311,106 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
).spread(function (user, group) { ).spread(function (user, group) {
return user.addGroup(group); return user.addGroup(group);
}).then(function () { }).then(function () {
return User.findOne({ return Promise.join(
User.findOne({
where: {}, where: {},
include: Group include: [Group],
}).then(function (user) { logging: console.log
return user; }),
User.findAll({
include: [Group],
logging: console.log
})
);
}); });
}); });
}); });
it('supports primary key attributes with different field names where parent include is required', function () {
var User = this.sequelize.define('User', {
id: {
type: DataTypes.UUID,
allowNull: false,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
field: 'user_id'
}
}, {
tableName: 'tbl_user'
});
var Company = this.sequelize.define('Company', {
id: {
type: DataTypes.UUID,
allowNull: false,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
field: 'company_id'
}
}, {
tableName: 'tbl_company'
});
var Group = this.sequelize.define('Group', {
id: {
type: DataTypes.UUID,
allowNull: false,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
field: 'group_id'
}
}, {
tableName: 'tbl_group'
});
var Company_has_Group = this.sequelize.define('Company_has_Group', {
}, {
tableName: 'tbl_company_has_group'
});
User.belongsTo(Company);
Company.hasMany(User);
Company.belongsToMany(Group, {through: Company_has_Group});
Group.belongsToMany(Company, {through: Company_has_Group});
return this.sequelize.sync({force: true}).then(function () {
return Promise.join(
User.create(),
Group.create(),
Company.create()
).spread(function (user, group, company) {
return Promise.join(
user.setCompany(company),
company.addGroup(group)
);
}).then(function () {
return Promise.join(
User.findOne({
where: {},
include: [
{model: Company, include: [Group]}
]
}),
User.findAll({
include: [
{model: Company, include: [Group]}
]
}),
User.findOne({
where: {},
include: [
{model: Company, required: true, include: [Group]}
]
}),
User.findAll({
include: [
{model: Company, required: true, include: [Group]}
]
})
);
});
});
}); });
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!