Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question]: Discriminator schema with Doctrine ORM Discriminator map #2262

Closed
deluxetom opened this issue Apr 9, 2024 · 2 comments
Closed
Labels

Comments

@deluxetom
Copy link
Contributor

Version

4.25.2

Question

I was trying to define the discriminator manually but I cant get it to work:

#[ApiDoc\Schema(
    title: 'Unlock',
    type: 'object',
    discriminator: new ApiDoc\Discriminator(propertyName: 'discriminator', mapping: [
        self::DISCRIMINATOR_FREE_TRIAL_LOW_LATENCY => UnlockFreeTrialLowLatency::class,
        self::DISCRIMINATOR_FREE_TRIAL_SOURCE      => UnlockFreeTrialSource::class,
        self::DISCRIMINATOR_PM_MEDIA               => UnlockPmMedia::class,
        self::DISCRIMINATOR_POST                   => UnlockPost::class,
        self::DISCRIMINATOR_SOCIAL                 => UnlockSocial::class,
        self::DISCRIMINATOR_SUB_CLUB               => UnlockSubClub::class,
        self::DISCRIMINATOR_GIFT                   => UnlockGift::class,
        self::DISCRIMINATOR_CLIP                   => UnlockClip::class,
    ]),
    oneOf: [
        new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialLowLatency::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialSource::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockPmMedia::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockPost::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockSocial::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockSubClub::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockGift::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockClip::class)),
    ],
)]

I end up with this:

                "discriminator": {
                    "propertyName": "discriminator",
                    "mapping": {
                        "free_trial_low_latency": "App\\Entity\\Unlock\\UnlockFreeTrialLowLatency",
                        "free_trial_source": "App\\Entity\\Unlock\\UnlockFreeTrialSource",
                        "pm_media": "App\\Entity\\Unlock\\UnlockPmMedia",
                        "post": "App\\Entity\\Unlock\\UnlockPost",
                        "social": "App\\Entity\\Unlock\\UnlockSocial",
                        "sub_club": "App\\Entity\\Unlock\\UnlockSubClub",
                        "gift": "App\\Entity\\Unlock\\UnlockGift",
                        "clip": "App\\Entity\\Unlock\\UnlockClip"
                    }
                },

and when I try this one:

#[ApiDoc\Schema(
    title: 'Unlock',
    type: 'object',
    discriminator: new ApiDoc\Discriminator(propertyName: 'discriminator', mapping: [
        self::DISCRIMINATOR_FREE_TRIAL_LOW_LATENCY => new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialLowLatency::class)),
        self::DISCRIMINATOR_FREE_TRIAL_SOURCE      => new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialSource::class)),
        self::DISCRIMINATOR_PM_MEDIA               => new ApiDoc\Schema(ref: new Model(type: UnlockPmMedia::class)),
        self::DISCRIMINATOR_POST                   => new ApiDoc\Schema(ref: new Model(type: UnlockPost::class)),
        self::DISCRIMINATOR_SOCIAL                 => new ApiDoc\Schema(ref: new Model(type: UnlockSocial::class)),
        self::DISCRIMINATOR_SUB_CLUB               => new ApiDoc\Schema(ref: new Model(type: UnlockSubClub::class)),
        self::DISCRIMINATOR_GIFT                   => new ApiDoc\Schema(ref: new Model(type: UnlockGift::class)),
        self::DISCRIMINATOR_CLIP                   => new ApiDoc\Schema(ref: new Model(type: UnlockClip::class)),
    ]),
    oneOf: [
        new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialLowLatency::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialSource::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockPmMedia::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockPost::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockSocial::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockSubClub::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockGift::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockClip::class)),
    ],
)]

the result is:

                "discriminator": {
                    "propertyName": "discriminator",
                    "mapping": {
                        "free_trial_low_latency": {
                            "$ref": "#/components/schemas/UnlockFreeTrialLowLatency"
                        },
                        "free_trial_source": {
                            "$ref": "#/components/schemas/UnlockFreeTrialSource"
                        },
                        "pm_media": {
                            "$ref": "#/components/schemas/UnlockPmMedia"
                        },
                        "post": {
                            "$ref": "#/components/schemas/UnlockPost"
                        },
                        "social": {
                            "$ref": "#/components/schemas/UnlockSocial"
                        },
                        "sub_club": {
                            "$ref": "#/components/schemas/UnlockSubClub"
                        },
                        "gift": {
                            "$ref": "#/components/schemas/UnlockGift"
                        },
                        "clip": {
                            "$ref": "#/components/schemas/UnlockClip"
                        }
                    }
                },

I'm trying to generate this:

                "discriminator": {
                    "propertyName": "discriminator",
                    "mapping": {
                        "free_trial_low_latency": "#/components/schemas/UnlockFreeTrialLowLatency",
                        "free_trial_source": "#/components/schemas/UnlockFreeTrialSource",
                        "pm_media": "#/components/schemas/UnlockPmMedia",
                        "post": "#/components/schemas/UnlockPost",
                        "social": "#/components/schemas/UnlockSocial",
                        "sub_club": "#/components/schemas/UnlockSubClub",
                        "gift": "#/components/schemas/UnlockGift",
                        "clip": "#/components/schemas/UnlockClip"
                    }
                },

any idea how I can achieve this?

Additional context

I tried using the JMS DiscriminatorMap but when I set the field name to the virtual property returning the discriminator, I get an error that it's a duplicate (the DB field name is different)

#[ORM\InheritanceType('SINGLE_TABLE')]
#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
#[ORM\DiscriminatorMap([
    self::DISCRIMINATOR_FREE_TRIAL_LOW_LATENCY => UnlockFreeTrialLowLatency::class,
    self::DISCRIMINATOR_FREE_TRIAL_SOURCE      => UnlockFreeTrialSource::class,
    self::DISCRIMINATOR_PM_MEDIA               => UnlockPmMedia::class,
    self::DISCRIMINATOR_POST                   => UnlockPost::class,
    self::DISCRIMINATOR_SOCIAL                 => UnlockSocial::class,
    self::DISCRIMINATOR_SUB_CLUB               => UnlockSubClub::class,
    self::DISCRIMINATOR_GIFT                   => UnlockGift::class,
    self::DISCRIMINATOR_CLIP                   => UnlockClip::class,
])]

any help would be appreciated, thank you!

@DjordyKoert
Copy link
Collaborator

DjordyKoert commented Apr 15, 2024

There is currently no real way to "translate" the Model attribute to a reference string for your example. In the meantime you should be able to do this by manually defining reference like so:

#[ApiDoc\Schema(
    title: 'Unlock',
    type: 'object',
    discriminator: new ApiDoc\Discriminator(propertyName: 'discriminator', mapping: [
        self::DISCRIMINATOR_FREE_TRIAL_LOW_LATENCY => '#/components/schemas/UnlockFreeTrialLowLatency',
        self::DISCRIMINATOR_FREE_TRIAL_SOURCE      => '#/components/schemas/UnlockFreeTrialSource',
        self::DISCRIMINATOR_PM_MEDIA               => '#/components/schemas/UnlockPmMedia',
        self::DISCRIMINATOR_POST                   => '#/components/schemas/UnlockPost',
        self::DISCRIMINATOR_SOCIAL                 => '#/components/schemas/UnlockSocial',
        self::DISCRIMINATOR_SUB_CLUB               => '#/components/schemas/UnlockSubClub',
        self::DISCRIMINATOR_GIFT                   => '#/components/schemas/UnlockGift',
        self::DISCRIMINATOR_CLIP                   => '#/components/schemas/UnlockClip',
    ]),
    oneOf: [
        new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialLowLatency::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockFreeTrialSource::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockPmMedia::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockPost::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockSocial::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockSubClub::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockGift::class)),
        new ApiDoc\Schema(ref: new Model(type: UnlockClip::class)),
    ],
)]

@deluxetom
Copy link
Contributor Author

Thanks @DjordyKoert, that's actually what I ended up doing for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants