apostrophecms / apostrophe

A full-featured, open-source content management framework built with Node.js that empowers organizations by combining in-context editing and headless architecture in a full-stack JS environment.
https://apostrophecms.com
Other
4.36k stars 590 forks source link

Update the 'withType' options in 'relationship' fields to allow an array of types #4310

Open rredaelli opened 1 year ago

rredaelli commented 1 year ago

Description

Currently, in 'relationship' fields in ApostropheCMS 3, the withType options only accepts a single string to specify the relationship type. However, in the previous version, ApostropheCMS 2, this property could accept an array of types, allowing for greater flexibility in managing relationships.

Example

Currently:

_customField: { label: 'custom', type: 'relationship', withType: 'type1', builders: { // Include only the information you need with a projection project: { title: 1, _url: 1 } } }

Proposal:

_customField: { label: 'custom', type: 'relationship', withType: ['type1', 'type2'], builders: { // Include only the information you need with a projection project: { title: 1, _url: 1 } } }

Motivation

This change would allow developers to define more complex relationships between content, simplifying data structure and making ApostropheCMS 3 even more powerful and adaptable to project-specific needs.

Thank you for your attention!

boutell commented 1 year ago

Yes, this is called a polymorphic relationship. There are internal tickets for this, but so far we haven't had a strong need for it. You can submit a request for it on our product roadmap:

https://portal.productboard.com/apostrophecms/1-product-roadmap/tabs/1-under-consideration

("Submit idea" button)

Currently the popular workaround is to use an array field. Within the array schema, add a select field to choose the type, and several relationship fields using if to limit which one is active based on the value of the select. This actually works rather well.

Shubham1450 commented 1 year ago

I wan to work on this issue @boutell

boutell commented 1 year ago

Anyone is welcome to take a look, but keep in mind this is a fairly significant feature that also has a design component.

rredaelli commented 1 year ago

@boutell I haven't submitted a request on your product roadmap yet. Could it be useful to do so?

boutell commented 1 year ago

Definitely.

rredaelli commented 12 months ago

Is there any update? Thank you

boutell commented 12 months ago

Not so far. Did you add it to the product roadmap site? Also let me know if you are working with one of our customers.

rredaelli commented 12 months ago

Yes, it has been added to the product roadmap. No, I am not working with any of yours customers.

The biggest issue is the following: to find another way of acting without using the polymorphic relationship, I created in percorso module a data structure like the following:

tappe: {
    label: 'Tappe Itinerario',
    type: 'array',
    fields: {
        add: {
            tipo: {
                label: 'Tipo',
                type: 'select',
                choices: [
                    {
                        label: 'Museo',
                        value: 'luoghi-musei',
                    },
                    {
                        label: 'Evento',
                        value: 'eventi',
                    },
                    {
                        label: 'Teatro',
                        value: 'luoghi-teatri',
                    },
                ],
                required: true,
            },
            _museo: {
                label: 'Museo',
                type: 'relationship',
                withType: 'luoghi-musei',
                max: 1,
                if: {
                    tipo: 'luoghi-musei',
                },
            },
            _evento: {
                label: 'Evento',
                type: 'relationship',
                withType: 'eventi',
                max: 1,
                if: {
                    tipo: 'eventi',
                },
            },
            _teatro: {
                label: 'Teatro',
                type: 'relationship',
                withType: 'luoghi-teatri',
                max: 1,
                if: {
                    tipo: 'luoghi-teatri',
                },
            },
        }
    }
},

This seems to work initially, but when I need to establish a reverse relationship, I encounter difficulties. For example, if I wanted to establish the reverse relationship on the _teatro field in the "luoghi-teatri" module, I should do something like this:

_percorsi: {
    type: "relationshipReverse",
    withType: "percorso",
    reverseOf: "_teatro",
}

but it doesn't work

boutell commented 12 months ago

Yes, reverse relationships are quite a pain with this setup. They should work, but you'd need one for each possibility and so on.

ezzle commented 3 months ago

I need the new feature too