考虑一个我有一个功能性JSON后端和管理员资源company
,user
和company_user
的情况。
数据如下
为company_user
资源类型提供单独的顶级资源视图非常容易;但它应该可以根据用户和每个公司进行编辑,最好是在user
或company
资源视图的标签上。
因此出现了问题:如何为user
资源创建一个标签,我可以列出当前的company
- 引用(company_user
行),但是在同一个标签中我需要一种理智的方式来执行以下功能:
company_user
集合中添加一行; 答案 0 :(得分:0)
处理这种关系的最简单方法是在模型上提供一个额外的字段,用作关系的表示。
例如,我们需要从用户那里看到他的公司:公开一个新字段user.company_ids
。
此字段不必在数据库中,您的API或代理可以在此字段中列出相关的公司ID,对于写请求,可以使用它来创建,更改或删除关系。
实施此字段后,admin-on-rest非常容易配置。 我制作了一个完整的代码片段:https://codesandbox.io/s/r04y8rn96p
首先,编写您的顶级资源:
<Admin
authClient={authClient}
restClient={restClient}
title="Example Admin"
locale="en"
messages={messages}
>
<Resource
name="companies"
list={CompanyList}
create={CompanyCreate}
edit={CompanyEdit}
show={CompanyShow}
remove={Delete}
icon={CompanyIcon}
/>
<Resource
name="users"
list={UserList}
create={UserCreate}
edit={UserEdit}
remove={Delete}
icon={UserIcon}
show={UserShow}
/>
<Resource
name="company_user"
icon={CompanyUserIcon}
list={CompanyUserList}
create={CompanyUserCreate}
show={CompanyUserShow}
remove={Delete}
/>
</Admin>
然后,您可以在额外字段上使用ReferenceArrayInput
作为用户模型,就像一对多关系一样。
export const UserEdit = ({ ...props }) => (
<Edit title={<UserTitle />} {...props}>
<TabbedForm>
<FormTab label="User Infos">
<TextInput source="name" />
<DateInput source="published_at" defaultValue={() => new Date()} />
<TextInput source="company_ids" />
</FormTab>
<FormTab label="Companies">
<ReferenceArrayInput source="company_ids" reference="companies">
<SelectArrayInput optionText="title" />
</ReferenceArrayInput>
</FormTab>
</TabbedForm>
</Edit>
);
由于想法是将关系模拟为额外字段,因此您可以通过restClient
从后端(最佳选择)或前端处理此字段。以下是只读关系的虚拟示例:
// It's better to implement these rules on the backend
const improvedRestClient = (type, resource, params) => {
return restClient(type, resource, params).then((response) => {
// Inject company_ids into user
if (type === 'GET_ONE' && resource === 'users') {
return restClient('GET_LIST', 'company_user', defaultOptions).then(({ data: companyUsers }) => {
const user = response.data;
return {
data: {
...user,
company_ids: companyUsers
.filter(item => item.user_id === user.id)
.map(item => item.company_id),
},
}
});
}
// Inject user_ids into company
if (type === 'GET_ONE' && resource === 'companies') {
return restClient('GET_LIST', 'company_user', defaultOptions).then(({ data: companyUsers }) => {
const company = response.data;
return {
data: {
...company,
user_ids: companyUsers
.filter(item => item.company_id === company.id)
.map(item => item.user_id),
},
}
});
}
return response;
});
};