diff --git a/lib/queryBuilder/graph/patch/GraphPatchAction.js b/lib/queryBuilder/graph/patch/GraphPatchAction.js index 33f3df339..4f87a2146 100644 --- a/lib/queryBuilder/graph/patch/GraphPatchAction.js +++ b/lib/queryBuilder/graph/patch/GraphPatchAction.js @@ -231,7 +231,10 @@ class GraphPatchAction extends GraphAction { } _createRootBuilder(node) { - return node.obj.$query(); + const currentNode = this.currentGraph.nodeForNode(node); + const currentObj = currentNode && currentNode.obj; + + return currentObj ? currentObj.$query() : node.obj.$query(); } } diff --git a/lib/queryBuilder/operations/DelegateOperation.js b/lib/queryBuilder/operations/DelegateOperation.js index 2440166b7..cf54965bd 100644 --- a/lib/queryBuilder/operations/DelegateOperation.js +++ b/lib/queryBuilder/operations/DelegateOperation.js @@ -11,6 +11,10 @@ class DelegateOperation extends QueryBuilderOperation { this.delegate = opt.delegate; } + get modelOptions() { + return this.delegate.modelOptions; + } + is(OperationClass) { return super.is(OperationClass) || this.delegate.is(OperationClass); } diff --git a/tests/integration/staticHooks.js b/tests/integration/staticHooks.js index bbf1f04cf..e3ffaf7e0 100644 --- a/tests/integration/staticHooks.js +++ b/tests/integration/staticHooks.js @@ -1163,6 +1163,32 @@ module.exports = (session) => { expect(queries.length).to.equal(4); }); + it('should be able to access modelOptions in beforeUpdate when using patchAndFetchById', async () => { + Movie.beforeUpdate = createHookSpy(({ modelOptions }) => { + chaiExpect(modelOptions).to.deep.equal({ patch: true }); + }); + + const hungerGames = await Movie.query().findOne('name', 'like', '%gam%'); + expect(queries.length).to.equal(1); + + await Movie.query().patchAndFetchById(hungerGames.id, { name: 'Updated' }); + expect(Movie.beforeUpdate.calls.length).to.equal(1); + }); + + it('should populate modelOptions with old data when using upsertGraph', async () => { + Movie.beforeUpdate = createHookSpy(({ modelOptions }) => { + expect(modelOptions).to.have.property('old'); + + chaiExpect(modelOptions.old).containSubset({ name: 'Hungergames' }); + }); + + const hungerGames = await Movie.query().findOne('name', 'like', '%gam%'); + expect(queries.length).to.equal(1); + + await Movie.query().upsertGraph({ id: hungerGames.id, name: 'Updated' }); + expect(Movie.beforeUpdate.calls.length).to.equal(1); + }); + it('should be able to cancel the query', () => { Movie.beforeUpdate = createHookSpy(({ cancelQuery }) => { cancelQuery();