[Question]: Discriminator schema with Doctrine ORM Discriminator map
Closed this issue · 2 comments
deluxetom commented
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 commented
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 commented
Thanks @DjordyKoert, that's actually what I ended up doing for now