I'm creating an application using the documentation provided by the KeystoneJS framework. So, in my application I have two tables, one is users and the other is posts. So, I'm wondering, when I create a post by logging into the admin area, there is a field with a foreign key column, and that field is empty to be populated with the foreign key value from the users table. So, when I create a new post using the logged in user's id in KeystoneJS, I want the system to automatically add the foreign key value to author.
So, I searched everywhere for a solution but failed to find a suitable one.
If anyone has any thoughts on this, it would be greatly appreciated if you could answer this question.
Thanks
P粉9491909722023-09-15 10:10:38
Have you seen Controlled blog examples?
It has lists similar to your project: Posts
and Users
, which can be Contributors
or Moderators
. In your case the contributor/admin distinction doesn't matter, you would be interested in the hooks on the Post
list, specifically the resolveInput.create
hook, it looks like this:
hooks: { resolveInput: { create: ({ context, resolvedData }) => { resolvedData.createdAt = new Date(); if (context.session?.contributor) { return { ...resolvedData, createdBy: { connect: { id: context.session?.contributor?.id, }, }, }; } return resolvedData; }, }, // 其他钩子... },
According to documentation:
So this is our opportunity to change the value before saving, including populating or forcing a value like your Post.author
field.
resolveInput
Gets the context
object, which includes a reference to the session
object. The contents of this object are determined by your session storage function, but usually contain information about the current user. In this example, if the logged in user is a contributor, we get their contributor ID from context.session?.contributor?.id
and save it to the createdBy
field . At the same time, the createdAt
field is also set to the current date and time.
Note that since this hook is configured at the list level, it should return the entire item's data (basically the resolvedData
object and any other changes the hook wants to make). An alternative would be to add the resolvedData
function at the field level, but then we would need two separate functions - one for createdAt
and another for createdBy
- Every function returns a single value. For more information on this distinction, see Hooks Guide.
Additionally, it is important not to confuse hooks with Access control - i.e. whether a contributor should be allowed to create a post in the first place. In this example, access control is configured separately, in the access
configuration of the list.
Final note - at the time of writing, the Hooks API documentation covers resolveInput
hooks (at both list and field levels), but does not break them down into different operations (i.e. resolveInput.create
and resolveInput.update
). This is just a recent syntax improvement, it doesn't change how hooks are used. If you only use the API in the document, the above code can be written as:
hooks: { resolveInput: ({ operation, context, resolvedData }) => { // 仅对创建操作运行(忽略更新) if (operation !== 'create') return resolvedData; resolvedData.createdAt = new Date(); if (context.session?.contributor) { return { ...resolvedData, createdBy: { connect: { id: context.session?.contributor?.id, }, }, }; } return resolvedData; }, // 其他钩子... },