英文:
Add logged in user ID to foreign key field automatically in KeystoneJS
问题
I'm creating an application in KeystoneJS with the documentation provided for that framework. So, in my application, there are 2 tables, one is user and the other one is post. So, I would like to know, when I'm creating a post by logging into the admin area, there is a field with the foreign key column and that field is empty to fill the foreign key values coming from the user table. So, I want the system to add foreign key value to author automatically when I'm creating a new post with the id of logged in user in KeystoneJS.
So, I looked for everywhere to find a solution for this and I failed to find a proper solution for this.
If anyone have any idea about this, please reply this question and it would be appreciate a lot.
Thank you
英文:
I'm creating an application in KeystoneJS with the documentation provided for that framework. So, in my application, there are 2 tables, one is user and the other one is post. So, I would like to know, when I'm creating a post by logging into the admin area, there is a field with the foreign key column and that field is empty to fill the foreign key values coming from the user table. So, I want the system to add foreign key value to author automatically when I'm creating a new post with the id of logged in user in KeystoneJS.
So, I looked for everywhere to find a solution for this and I failed to find a proper solution for this.
If anyone have any idea about this, please reply this question and it would be appreciate a lot.
Thank you
答案1
得分: 1
你看过审查博客示例吗?
它有类似于你的项目的列表:Posts
和Users
,可以是Contributors
或Moderators
。在你的情况下,贡献者/管理员的区别并不重要,你可能会对Post
列表上的钩子感兴趣,特别是resolveInput.create
钩子,它看起来像这样:
hooks: {
resolveInput: {
create: ({ context, resolvedData }) => {
resolvedData.createdAt = new Date();
if (context.session?.contributor) {
return {
...resolvedData,
createdBy: {
connect: {
id: context.session?.contributor?.id,
},
},
};
}
return resolvedData;
},
},
// 其他钩子...
},
根据文档:
> resolveInput
函数用于修改或增强传递给create
或update
操作的数据值。
因此,这是我们改变值的机会,然后保存它们,包括填充或强制执行像你的Post.author
字段这样的值。
resolveInput
获取context
对象,其中包括对session
对象的引用。这个对象的内容由你的会话存储函数决定,但通常包含有关当前用户的信息。在此示例中,如果登录的用户是贡献者,我们从context.session?.contributor?.id
获取其贡献者ID,并将其保存到createdBy
字段。createdAt
字段也设置为当前日期和时间。
请注意,由于此钩子在列表级别配置,应该返回整个项目的数据(基本上是resolvedData
对象以及钩子想要进行的任何其他更改)。另一种方法是在字段级别添加resolvedData
函数,但然后我们将需要两个单独的函数 - 一个用于createdAt
,另一个用于createdBy
– 两者都会返回一个单一的值。请参阅钩子指南以了解更多关于此区别的信息。
还要注意,不要混淆钩子与访问控制– 即贡献者是否允许在首次创建帖子。在这个示例中,访问控制是单独配置的,位于列表的access
配置中,这也是应该的。
最后注意一下 – 在撰写本文时,钩子API文档涵盖了resolveInput
钩子(在列表和字段级别),但没有将其分解为不同的操作(即resolveInput.create
和resolveInput.update
)。这只是一个最近的语法改进,它并没有改变关于如何使用钩子的基本内容。如果只使用文档化的API,上面的代码可以写成:
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;
},
// 其他钩子...
},
英文:
Have you looked at the moderated blog example?
It has lists similar to your project: Posts
and Users
, that can be Contributors
or Moderators
. The contributor/moderator distinction doesn't matter much in your case, the part you'll be interested in are the hooks on the Post
list, specifically the resolveInput.create
hook, which 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;
},
},
// Other hooks...
},
As per the docs:
> The resolveInput
function is used to modify or augment the data values passed in to a create
or update
operation.
So this is our chance to change values before they're saved, including populating or enforcing values like your Post.author
field.
resolveInput
gets the context
object, which includes a reference to the session
object. The contents of this object is determine by your session store functions but usually contains info about the current user. In this example, if the user signed in is a contributor, we get their contributor Id from context.session?.contributor?.id
and save it to the createdBy
field. The createdAt
field is also set to the current date and time.
Note that, because this hook is configured at the list level, data for the whole item should be returned (basically, the resolvedData
object with any additional changes the hook wants to make). Another way to do this would be to add resolvedData
functions at the field level but then we'd need two separate functions - one for createdAt
and another for createdBy
– each of which would return a single value. See the hooks guide for more on this distinction.
Also, its important not to conflate hooks with access control – ie. whether a contributor should be allowed to create a post in the first place. In this example access control is configured separately, up in the list access
config, as it should be.
One final note – at the time of writing the hook API docs cover the resolveInput
hook (at the list and field levels), but don't break it down into the different operations (ie. resolveInput.create
and resolveInput.update
). This is just a recent syntactic improvement, it doesn't change anything fundamental about how hooks are to be used. If using just the documented API, the code above could be written as:
hooks: {
resolveInput: ({ operation, context, resolvedData }) => {
// Only run for create operations (so ignore updates)
if (operation !== 'create') return resolvedData;
resolvedData.createdAt = new Date();
if (context.session?.contributor) {
return {
...resolvedData,
createdBy: {
connect: {
id: context.session?.contributor?.id,
},
},
};
}
return resolvedData;
},
// Other hooks...
},
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论