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

Commit e710a423 by Luc Verdier Committed by Jan Aagaard Meier

Add context and custom options to nested creation (#5790)

1 parent c3179058
# Future
- [FIXED] Method QueryInterface.bulkDelete no longer working when the model parameter is missing. (PostgreSQL) [#5615](https://github.com/sequelize/sequelize/issues/5615)
- [ADDED] Context and custom options for deep creation
# 3.22.0
- [FIXED] Fix defaultValues getting overwritten on build
......
......@@ -634,10 +634,15 @@ Instance.prototype.save = function(options) {
var instance = self.get(include.as);
if (!instance) return Promise.resolve();
return instance.save({
transaction: options.transaction,
logging: options.logging
}).then(function () {
var includeOptions = _(self.$Model.$optClone(include))
.omit(['association'])
.defaults({
transaction: options.transaction,
logging: options.logging,
parentRecord: self
}).value();
return instance.save(includeOptions).then(function () {
return self[include.association.accessors.set](instance, {save: false, logging: options.logging});
});
});
......@@ -707,18 +712,26 @@ Instance.prototype.save = function(options) {
if (!Array.isArray(instances)) instances = [instances];
if (!instances.length) return Promise.resolve();
var includeOptions = _(self.$Model.$optClone(include))
.omit(['association'])
.defaults({
transaction: options.transaction,
logging: options.logging,
parentRecord: self
}).value();
// Instances will be updated in place so we can safely treat HasOne like a HasMany
return Promise.map(instances, function (instance) {
if (include.association instanceof BelongsToMany) {
return instance.save({transaction: options.transaction, logging: options.logging}).then(function () {
return instance.save(includeOptions).then(function () {
var values = {};
values[include.association.foreignKey] = self.get(self.Model.primaryKeyAttribute, {raw: true});
values[include.association.otherKey] = instance.get(instance.Model.primaryKeyAttribute, {raw: true});
return include.association.throughModel.create(values, {transaction: options.transaction, logging: options.logging});
return include.association.throughModel.create(values, includeOptions);
});
} else {
instance.set(include.association.foreignKey, self.get(self.Model.primaryKeyAttribute, {raw: true}));
return instance.save({transaction: options.transaction, logging: options.logging});
return instance.save(includeOptions);
}
});
});
......
......@@ -17,6 +17,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var User = this.sequelize.define('User', {
first_name: Sequelize.STRING,
last_name: Sequelize.STRING
}, {
hooks: {
beforeCreate: function (user, options) {
user.createOptions = options;
}
}
});
Product.belongsTo(User);
......@@ -29,8 +35,13 @@ describe(Support.getTestDialectTeaser('Model'), function() {
last_name: 'Broadstone'
}
}, {
include: [ User ]
include: [{
model: User,
myOption: 'option'
}]
}).then(function(savedProduct) {
expect(savedProduct.User.createOptions.myOption).to.be.equal('option');
expect(savedProduct.User.createOptions.parentRecord).to.be.equal(savedProduct);
return Product.findOne({
where: { id: savedProduct.id },
include: [ User ]
......@@ -82,6 +93,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
var Tag = this.sequelize.define('Tag', {
name: Sequelize.STRING
}, {
hooks: {
afterCreate: function (tag, options) {
tag.createOptions = options;
}
}
});
Product.hasMany(Tag);
......@@ -95,7 +112,10 @@ describe(Support.getTestDialectTeaser('Model'), function() {
{id: 2, name: 'Beta'}
]
}, {
include: [ Tag ]
include: [{
model: Tag,
myOption: 'option'
}]
}).then(function(savedProduct) {
return Product.find({
where: { id: savedProduct.id },
......@@ -209,6 +229,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var Task = this.sequelize.define('Task', {
title: DataTypes.STRING,
active: DataTypes.BOOLEAN
}, {
hooks: {
afterCreate: function (task, options) {
task.createOptions = options;
}
}
});
User.belongsToMany(Task, {through: 'user_task'});
......@@ -222,8 +248,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
{ title: 'Die trying', active: false }
]
}, {
include: [ Task ]
include: [{
model: Task,
myOption: 'option'
}]
}).then(function(savedUser) {
expect(savedUser.Tasks[0].createOptions.myOption).to.be.equal('option');
expect(savedUser.Tasks[0].createOptions.parentRecord).to.be.equal(savedUser);
expect(savedUser.Tasks[1].createOptions.myOption).to.be.equal('option');
expect(savedUser.Tasks[1].createOptions.parentRecord).to.be.equal(savedUser);
return User.find({
where: { id: savedUser.id },
include: [ Task ]
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!