Skip to content

Wrong hook invoked when db.foreignKey: true is set #9433

@dcousens

Description

@dcousens

Discussed in #9432

Originally posted by plap979 December 13, 2024
Hi,
before to start, let me thank all the Keystone people. Keystone’s simply great! I dreamed about a tool like this by years... I hope I can help somehow with this bug report.

How to reproduce

I just created a fresh new app with npm create keystone-app@latest and I just added these 2 lists:

  Truck: list({
    access: allowAll,
    fields: {
      plate: text(),
      trailer: relationship({
        ref: "Trailer.truck",
        many: false
      })
    },
    hooks: {
      afterOperation({listKey, operation, item}){
        console.info(`${listKey} ${operation}d: ${JSON.stringify(item)}`)
      }
    }
  }),

  Trailer: list({
    access: allowAll,
    fields: {
      plate: text(),
      truck: relationship({
        ref: "Truck.trailer",
        many: false,
        db: { foreignKey: true }
      })
    },
    hooks: {
      afterOperation({listKey, operation, item}){
        console.info(`${listKey} ${operation}d: ${JSON.stringify(item)}`)
      }
    }
  }),

Basically, they're just 2 entities in a 1-to-1 optional relationship and with the same afterOperation list hook. Now:

  • Launch the app,
  • pass the welcome wizard,
  • create a truck with no trailer and
  • create a trailer with no truck.

You will read:

Truck created: {"id":"cm4lkboxa0003rvnuxozfrgq3","plate":"AA000AA"}
Trailer created: {"id":"cm4lkbwuk0004rvnuqlhgy694","plate":"BB111BB","truckId":null}

Note how truckId is given when the trailer mutates but not the other way around. I like it. It shows us that the hook api is more near to the database than the client side. Even the Hooks API doc itself, telling about item and originalItem, says “This object is an internal database item”, which slightly confirms my thought.

Now mutate the trailer to link it and to unlink to and from the truck. You will read:

Trailer updated: {"id":"cm4lkbwuk0004rvnuqlhgy694","plate":"BB111BB","truckId":"cm4lkboxa0003rvnuxozfrgq3"}
Trailer updated: {"id":"cm4lkbwuk0004rvnuqlhgy694","plate":"BB111BB","truckId":null}

and that’s wonderful. Now do the same, but from the truck side, by navigating the Admin UI to the truck, or by the api explorer (with updateTruck mutation)

Truck updated: {"id":"cm4lkboxa0003rvnuxozfrgq3","plate":"AA000AA"}
Truck updated: {"id":"cm4lkboxa0003rvnuxozfrgq3","plate":"AA000AA"}

Unexpected behavior

I found this an unexpected behavior. I expected that Keystone invokes the Trailer hook rather than the Truck hook:

  1. on the truck side nothing changed,
  2. on the trailer side something changed,
  3. Hooks are near the db structure

Currently my node.js is v20.18.0 and my package.json contains:

"dependencies": {
  "@keystone-6/auth": "^8.0.0",
  "@keystone-6/core": "^6.0.0",
  "@keystone-6/fields-document": "^9.0.0",
  "typescript": "^5.5.0"
}

I think this bug could be related to #7301.

Tnx

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions