feat: join field across many collections (#10919)
This feature allows you to specify `collection` for the join field as
array.
This can be useful for example to describe relationship linking like
this:
```ts
{
slug: 'folders',
fields: [
{
type: 'join',
on: 'folder',
collection: ['files', 'documents', 'folders'],
name: 'children',
},
{
type: 'relationship',
relationTo: 'folders',
name: 'folder',
},
],
},
{
slug: 'files',
upload: true,
fields: [
{
type: 'relationship',
relationTo: 'folders',
name: 'folder',
},
],
},
{
slug: 'documents',
fields: [
{
type: 'relationship',
relationTo: 'folders',
name: 'folder',
},
],
},
```
Documents and files can be placed to folders and folders themselves can
be nested to other folders (root folders just have `folder` as `null`).
Output type of `Folder`:
```ts
export interface Folder {
id: string;
children?: {
docs?:
| (
| {
relationTo?: 'files';
value: string | File;
}
| {
relationTo?: 'documents';
value: string | Document;
}
| {
relationTo?: 'folders';
value: string | Folder;
}
)[]
| null;
hasNextPage?: boolean | null;
} | null;
folder?: (string | null) | Folder;
updatedAt: string;
createdAt: string;
}
```
While you could instead have many join fields (for example
`childrenFolders`, `childrenFiles`) etc - this doesn't allow you to
sort/filter and paginate things across many collections, which isn't
trivial. With SQL we use `UNION ALL` query to achieve that.
---------
Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
@@ -220,6 +220,120 @@ export default buildConfigWithDefaults({
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'multiple-collections-parents',
|
||||
fields: [
|
||||
{
|
||||
type: 'join',
|
||||
name: 'children',
|
||||
collection: ['multiple-collections-1', 'multiple-collections-2'],
|
||||
on: 'parent',
|
||||
admin: {
|
||||
defaultColumns: ['title', 'name', 'description'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'multiple-collections-1',
|
||||
admin: { useAsTitle: 'title' },
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
relationTo: 'multiple-collections-parents',
|
||||
name: 'parent',
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'multiple-collections-2',
|
||||
admin: { useAsTitle: 'title' },
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
relationTo: 'multiple-collections-parents',
|
||||
name: 'parent',
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
slug: 'folders',
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
relationTo: 'folders',
|
||||
name: 'folder',
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
type: 'join',
|
||||
name: 'children',
|
||||
collection: ['folders', 'example-pages', 'example-posts'],
|
||||
on: 'folder',
|
||||
admin: {
|
||||
defaultColumns: ['title', 'name', 'description'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'example-pages',
|
||||
admin: { useAsTitle: 'title' },
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
relationTo: 'folders',
|
||||
name: 'folder',
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'example-posts',
|
||||
admin: { useAsTitle: 'title' },
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
relationTo: 'folders',
|
||||
name: 'folder',
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
localization: {
|
||||
locales: [
|
||||
|
||||
Reference in New Issue
Block a user