-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Description
Feature Description
Currently, there is no way to do Single Table Inheritance when splitting the entity definition from its database model by using Entity Schemas.
This feature request proposes a means to add support for this functionality on Entity Schemas.
The Solution
When defining an inheritance tree of entities, such as:
abstract class Base {
id!: number
type!: string
createdAt!: Date
updatedAt!: Date
}
class A extends Base {
constructor(public a: boolean) {
super()
}
}
class B extends Base {
constructor(public b: number) {
super()
}
}
class C extends Base {
constructor(public c: string) {
super()
}
}It should be possible to define corresponding Entity Schemas specifying their inheritance relationships:
- Which one is the parent class and which ones are their children
- Which column should be used as the discriminator value
The proposed solution is to add a new inheritance option for informing the inheritance pattern to be used, alongside the discriminator column (also, note the use of type: "entity-child" for the concrete entities' schemas):
const BaseSchema = new EntitySchema<Base>({
target: Base,
name: "Base",
columns: {
id: {
type: Number,
primary: true,
generated: "increment",
},
type: {
type: String,
},
createdAt: {
type: Date,
createDate: true,
},
updatedAt: {
type: Date,
updateDate: true,
},
},
// NEW: Inheritance options
inheritance: {
pattern: "STI",
column: "type",
},
})
const ASchema = new EntitySchema<A>({
target: A,
name: "A",
type: "entity-child",
columns: {
...BaseSchema.options.columns,
a: {
type: Boolean,
},
},
})
const BSchema = new EntitySchema<B>({
target: B,
name: "B",
type: "entity-child",
columns: {
...BaseSchema.options.columns,
b: {
type: Number,
},
},
})
const CSchema = new EntitySchema<C>({
target: C,
name: "C",
type: "entity-child",
columns: {
...BaseSchema.options.columns,
c: {
type: String,
},
},
})This should keep things cohesive to the current way of implementing STI, with the @TableInheritance and @ChildEntity decorators.
Considered Alternatives
I tried specifying the inheritance relationship through the current extends option, but I figure this property isn't really doing anything. In fact, doing this throws an exception while building the Entity Metadata from the schema:
// ...
const BSchema = new EntitySchema<B>({
// Throws "TypeError: Cannot read properties of undefined (reading 'ownColumns')"
extends: "Base",
target: B,
name: "B",
type: "entity-child",
columns: {
...BaseSchema.options.columns,
b: {
type: Number,
},
},
})
// ...Additional Context
This is partially related to issue #8415.
Relevant Database Driver(s)
- aurora-mysql
- aurora-postgres
- better-sqlite3
- cockroachdb
- cordova
- expo
- mongodb
- mysql
- nativescript
- oracle
- postgres
- react-native
- sap
- spanner
- sqlite
- sqlite-abstract
- sqljs
- sqlserver
Are you willing to resolve this issue by submitting a Pull Request?
Yes, I have the time, and I know how to start.