Skip to content

Commit a41ca28

Browse files
committed
Merge pull request #619 from ParsePlatform/nlutsenko.triggers.inflate
Improve beforeSave triggers for newly created objects.
2 parents 1ae61c9 + ae82f33 commit a41ca28

File tree

4 files changed

+70
-12
lines changed

4 files changed

+70
-12
lines changed

spec/ParseAPI.spec.js

+42
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,48 @@ describe('miscellaneous', function() {
533533
done();
534534
});
535535
});
536+
537+
it('pointer mutation properly saves object', done => {
538+
let className = 'GameScore';
539+
540+
Parse.Cloud.beforeSave(className, (req, res) => {
541+
let object = req.object;
542+
expect(object instanceof Parse.Object).toBeTruthy();
543+
544+
let child = object.get('child');
545+
expect(child instanceof Parse.Object).toBeTruthy();
546+
child.set('a', 'b');
547+
child.save().then(() => {
548+
res.success();
549+
});
550+
});
551+
552+
let obj = new Parse.Object(className);
553+
obj.set('foo', 'bar');
554+
555+
let child = new Parse.Object('Child');
556+
child.save().then(() => {
557+
obj.set('child', child);
558+
return obj.save();
559+
}).then(() => {
560+
let query = new Parse.Query(className);
561+
query.include('child');
562+
return query.get(obj.id).then(objAgain => {
563+
expect(objAgain.get('foo')).toEqual('bar');
564+
565+
let childAgain = objAgain.get('child');
566+
expect(childAgain instanceof Parse.Object).toBeTruthy();
567+
expect(childAgain.get('a')).toEqual('b');
568+
569+
return Promise.resolve();
570+
});
571+
}).then(() => {
572+
done();
573+
}, error => {
574+
fail(error);
575+
done();
576+
});
577+
});
536578
});
537579

538580
it('test afterSave get full object on create and update', function(done) {

src/RestWrite.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,24 @@ RestWrite.prototype.validateSchema = function() {
111111
// Runs any beforeSave triggers against this operation.
112112
// Any change leads to our data being mutated.
113113
RestWrite.prototype.runBeforeTrigger = function() {
114+
// Avoid doing any setup for triggers if there is no 'beforeSave' trigger for this class.
115+
if (!triggers.triggerExists(this.className, triggers.Types.beforeSave)) {
116+
return Promise.resolve();
117+
}
118+
114119
// Cloud code gets a bit of extra data for its objects
115120
var extraData = {className: this.className};
116121
if (this.query && this.query.objectId) {
117122
extraData.objectId = this.query.objectId;
118123
}
119124

120125
let originalObject = null;
121-
let updatedObject = null;
126+
let updatedObject = triggers.inflate(extraData, this.originalData);
122127
if (this.query && this.query.objectId) {
123128
// This is an update for existing object.
124129
originalObject = triggers.inflate(extraData, this.originalData);
125-
updatedObject = triggers.inflate(extraData, this.originalData);
126-
updatedObject.set(Parse._decode(undefined, this.data));
127-
} else {
128-
// This is create of an object, so no original object exists.
129-
// TODO: (nlutsenko) Use the same flow as for creation, when _Session triggers support is removed.
130-
updatedObject = triggers.inflate(extraData, this.data);
131130
}
131+
updatedObject.set(Parse._decode(undefined, this.data));
132132

133133
return Promise.resolve().then(() => {
134134
return triggers.maybeRunTrigger(

src/index.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -211,24 +211,35 @@ function addParseCloud() {
211211
afterDelete: {}
212212
};
213213

214+
function validateClassNameForTriggers(className) {
215+
const restrictedClassNames = [ '_Session' ];
216+
if (restrictedClassNames.indexOf(className) != -1) {
217+
throw `Triggers are not supported for ${className} class.`;
218+
}
219+
}
220+
214221
Parse.Cloud.define = function(functionName, handler, validationHandler) {
215222
Parse.Cloud.Functions[functionName] = handler;
216223
Parse.Cloud.Validators[functionName] = validationHandler;
217224
};
218225
Parse.Cloud.beforeSave = function(parseClass, handler) {
219-
var className = getClassName(parseClass);
226+
let className = getClassName(parseClass);
227+
validateClassNameForTriggers(className);
220228
Parse.Cloud.Triggers.beforeSave[className] = handler;
221229
};
222230
Parse.Cloud.beforeDelete = function(parseClass, handler) {
223-
var className = getClassName(parseClass);
231+
let className = getClassName(parseClass);
232+
validateClassNameForTriggers(className);
224233
Parse.Cloud.Triggers.beforeDelete[className] = handler;
225234
};
226235
Parse.Cloud.afterSave = function(parseClass, handler) {
227-
var className = getClassName(parseClass);
236+
let className = getClassName(parseClass);
237+
validateClassNameForTriggers(className);
228238
Parse.Cloud.Triggers.afterSave[className] = handler;
229239
};
230240
Parse.Cloud.afterDelete = function(parseClass, handler) {
231-
var className = getClassName(parseClass);
241+
let className = getClassName(parseClass);
242+
validateClassNameForTriggers(className);
232243
Parse.Cloud.Triggers.afterDelete[className] = handler;
233244
};
234245
Parse.Cloud.httpRequest = httpRequest;

src/triggers.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ var getTrigger = function(className, triggerType) {
1818
return undefined;
1919
};
2020

21+
function triggerExists(className: string, type: string): boolean {
22+
return (getTrigger(className, type) != undefined);
23+
}
24+
2125
var getRequestObject = function(triggerType, auth, parseObject, originalParseObject) {
2226
var request = {
2327
triggerName: triggerType,
@@ -52,7 +56,7 @@ var getResponseObject = function(request, resolve, reject) {
5256
success: function() {
5357
var response = {};
5458
if (request.triggerName === Types.beforeSave) {
55-
response['object'] = request.object.toJSON();
59+
response['object'] = request.object._getSaveJSON();
5660
}
5761
return resolve(response);
5862
},
@@ -96,5 +100,6 @@ module.exports = {
96100
getRequestObject: getRequestObject,
97101
inflate: inflate,
98102
maybeRunTrigger: maybeRunTrigger,
103+
triggerExists: triggerExists,
99104
Types: Types
100105
};

0 commit comments

Comments
 (0)