Skip to content

patch/update when $beforeUpdate modifies instance fields #71

@purepear

Description

@purepear

Some code first:

// MODEL DEFINITION
export default class Person extends Model{
  static tableName = 'Person';

  static jsonSchema = {
    type: 'object',
    required: [],
    properties: {
      id         : {type: 'integer'},
      firstName  : {type: 'string', default: ''},
      lastName   : {type: 'string', default: ''},
      fullName   : {type: 'string', default: ''},
      bigThing   : {type: 'string', default: ''}
    }
  };

  $beforeInsert(opt, queryContext){
    super.$beforeInsert(opt, queryContext)
    this.fullName = this.firstName+' '+this.lastName
  }

  $beforeUpdate(opt, queryContext){
    super.$beforeUpdate(opt, queryContext)
    this.fullName = this.firstName+' '+this.lastName
  }
}


// INITIALIZE AND RUN TEST
async function test(testCase){
  await Person.query().delete()
  await Person.query().insert({
    id: 1,
    firstName: 'John',
    lastName: 'Doe',
    bigThing: 'SOME BIG THING'
  })

  console.log("\n\n----------------- "+testCase.name+" -----------------")
  var person = await Person.query().findById(1)
  await testCase(person, {lastName: 'Smith'})
  console.log(await person.$query())
}


// TEST CASES
async function testCase1(person, change){
  await person.$query().patch(change).debug()
}

async function testCase2(person, change){
  await person.$query().update(change).debug()
}

async function testCase3(person, change){
  person.$setJson(change, {patch: true})
  await person.$query().update().debug()
}

async function testCase4(person, change){
  await person.$query().patch(Object.assign({firstName: person.firstName}, change)).debug()
}


// RUN TESTS
(async function(){
  try {
    await test(testCase1)
    await test(testCase2)
    await test(testCase3)
    await test(testCase4)
    process.exit()
  } catch(error) {
    console.error(error);
    process.exit()
  }
})()

And the results:

----------------- testCase1 -----------------
{ method: 'update',
  options: {},
  bindings: [ 'undefined Smith', 'Smith', 1 ],
  sql: 'update "Person" set "fullName" = ?, "lastName" = ? where "Person"."id" = ?',
  returning: undefined }
Person {
  id: 1,
  firstName: 'John',
  lastName: 'Smith',
  fullName: 'undefined Smith',
  bigThing: 'SOME BIG THING' }


----------------- testCase2 -----------------
{ method: 'update',
  options: {},
  bindings: [ '', '', ' Smith', 'Smith', 1 ],
  sql: 'update "Person" set "bigThing" = ?, "firstName" = ?, "fullName" = ?, "lastName" = ? where "Person"."id" = ?',
  returning: undefined }
Person {
  id: 1,
  firstName: '',
  lastName: 'Smith',
  fullName: ' Smith',
  bigThing: '' }


----------------- testCase3 -----------------
{ method: 'update',
  options: {},
  bindings: [ 'SOME BIG THING', 'John', 'John Smith', 'Smith', 1 ],
  sql: 'update "Person" set "bigThing" = ?, "firstName" = ?, "fullName" = ?, "lastName" = ? where "Person"."id" = ?',
  returning: undefined }
Person {
  id: 1,
  firstName: 'John',
  lastName: 'Smith',
  fullName: 'John Smith',
  bigThing: 'SOME BIG THING' }


----------------- testCase4 -----------------
{ method: 'update',
  options: {},
  bindings: [ 'John', 'John Smith', 'Smith', 1 ],
  sql: 'update "Person" set "firstName" = ?, "fullName" = ?, "lastName" = ? where "Person"."id" = ?',
  returning: undefined }
Person {
  id: 1,
  firstName: 'John',
  lastName: 'Smith',
  fullName: 'John Smith',
  bigThing: 'SOME BIG THING' }

What i ideally would want is when i run person.$query().patch(change) - objection/knex to detect the additional change in $beforeUpdate and include only the necessary fields in ths SQL query

update "Person" set "fullName" = ?, "lastName" = ? where "Person"."id" = ?'

Any idea how this could happen?

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions