|
|
@ -1,5 +1,5 @@
|
|
|
|
import {ModelKey, QueryRow, QuerySource} from '../types'
|
|
|
|
import {ModelKey, QueryRow, QuerySource} from '../types'
|
|
|
|
import {Container, Inject, Instantiable, isInstantiable} from '../../di'
|
|
|
|
import {Container, Inject, Instantiable, isInstantiable, StaticClass, StaticThis} from '../../di'
|
|
|
|
import {DatabaseService} from '../DatabaseService'
|
|
|
|
import {DatabaseService} from '../DatabaseService'
|
|
|
|
import {ModelBuilder} from './ModelBuilder'
|
|
|
|
import {ModelBuilder} from './ModelBuilder'
|
|
|
|
import {getFieldsMeta, ModelField} from './Field'
|
|
|
|
import {getFieldsMeta, ModelField} from './Field'
|
|
|
@ -19,13 +19,13 @@ import {HasOne} from './relation/HasOne'
|
|
|
|
import {HasMany} from './relation/HasMany'
|
|
|
|
import {HasMany} from './relation/HasMany'
|
|
|
|
import {HasOneOrMany} from './relation/HasOneOrMany'
|
|
|
|
import {HasOneOrMany} from './relation/HasOneOrMany'
|
|
|
|
import {Scope, ScopeClosure} from './scope/Scope'
|
|
|
|
import {Scope, ScopeClosure} from './scope/Scope'
|
|
|
|
import {LocalBus} from '../../support/bus/LocalBus'
|
|
|
|
import {LocalBus} from '../../support/bus'
|
|
|
|
import {ModelEvent} from './events/ModelEvent'
|
|
|
|
import {ModelEvent} from './events/ModelEvent'
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Base for classes that are mapped to tables in a database.
|
|
|
|
* Base for classes that are mapped to tables in a database.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>> {
|
|
|
|
export abstract class Model extends LocalBus<ModelEvent> {
|
|
|
|
@Inject()
|
|
|
|
@Inject()
|
|
|
|
protected readonly logging!: Logging
|
|
|
|
protected readonly logging!: Logging
|
|
|
|
|
|
|
|
|
|
|
@ -88,7 +88,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* Relations that should be eager-loaded by default.
|
|
|
|
* Relations that should be eager-loaded by default.
|
|
|
|
* @protected
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected with: (keyof T)[] = []
|
|
|
|
protected with: (keyof this)[] = []
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* The original row fetched from the database.
|
|
|
|
* The original row fetched from the database.
|
|
|
@ -100,7 +100,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* Cache of relation instances by property accessor.
|
|
|
|
* Cache of relation instances by property accessor.
|
|
|
|
* This is used by the `@Relation()` decorator to cache Relation instances.
|
|
|
|
* This is used by the `@Relation()` decorator to cache Relation instances.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public relationCache: Collection<{ accessor: string | symbol, relation: Relation<T, any, any> }> = new Collection<{accessor: string | symbol; relation: Relation<T, any, any>}>()
|
|
|
|
public relationCache: Collection<{ accessor: string | symbol, relation: Relation<any, any, any> }> = new Collection<{accessor: string | symbol; relation: Relation<any, any, any>}>()
|
|
|
|
|
|
|
|
|
|
|
|
protected scopes: Collection<{ accessor: string | Instantiable<Scope>, scope: ScopeClosure }> = new Collection<{accessor: string | Instantiable<Scope>; scope: ScopeClosure}>()
|
|
|
|
protected scopes: Collection<{ accessor: string | Instantiable<Scope>, scope: ScopeClosure }> = new Collection<{accessor: string | Instantiable<Scope>; scope: ScopeClosure}>()
|
|
|
|
|
|
|
|
|
|
|
@ -148,7 +148,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* const user = await UserModel.query<UserModel>().where('name', 'LIKE', 'John Doe').first()
|
|
|
|
* const user = await UserModel.query<UserModel>().where('name', 'LIKE', 'John Doe').first()
|
|
|
|
* ```
|
|
|
|
* ```
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static query<T2 extends Model<T2>>(): ModelBuilder<T2> {
|
|
|
|
public static query<T2 extends Model>(this: StaticThis<T2, any[]> & typeof Model): ModelBuilder<T2> {
|
|
|
|
const builder = <ModelBuilder<T2>> Container.getContainer().make<ModelBuilder<T2>>(ModelBuilder, this)
|
|
|
|
const builder = <ModelBuilder<T2>> Container.getContainer().make<ModelBuilder<T2>>(ModelBuilder, this)
|
|
|
|
const source: QuerySource = this.querySource()
|
|
|
|
const source: QuerySource = this.querySource()
|
|
|
|
|
|
|
|
|
|
|
@ -174,7 +174,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
} else if ( this.constructor.length < 1 ) {
|
|
|
|
} else if ( this.constructor.length < 1 ) {
|
|
|
|
// Otherwise, if we can instantiate the model without any arguments,
|
|
|
|
// Otherwise, if we can instantiate the model without any arguments,
|
|
|
|
// do that and get the eager-loaded relations directly.
|
|
|
|
// do that and get the eager-loaded relations directly.
|
|
|
|
const inst = Container.getContainer().make<Model<any>>(this)
|
|
|
|
const inst = Container.getContainer().make<Model>(this)
|
|
|
|
if ( Array.isArray(inst.with) ) {
|
|
|
|
if ( Array.isArray(inst.with) ) {
|
|
|
|
for (const relation of inst.with) {
|
|
|
|
for (const relation of inst.with) {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
@ -189,7 +189,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
builder.withScopes(this.prototype.scopes)
|
|
|
|
builder.withScopes(this.prototype.scopes)
|
|
|
|
} else if ( this.constructor.length < 1 ) {
|
|
|
|
} else if ( this.constructor.length < 1 ) {
|
|
|
|
// Otherwise, try to instantiate the model if possible and load the scopes that way
|
|
|
|
// Otherwise, try to instantiate the model if possible and load the scopes that way
|
|
|
|
const inst = Container.getContainer().make<Model<any>>(this)
|
|
|
|
const inst = Container.getContainer().make<Model>(this)
|
|
|
|
builder.withScopes(inst.scopes)
|
|
|
|
builder.withScopes(inst.scopes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -247,7 +247,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
this.setFieldFromObject(field.modelKey, field.databaseKey, row)
|
|
|
|
this.setFieldFromObject(field.modelKey, field.databaseKey, row)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
await this.push(new ModelRetrievedEvent<T>(this as any))
|
|
|
|
await this.push(new ModelRetrievedEvent<this>(this as any))
|
|
|
|
return this
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -329,9 +329,9 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* .update({ username: 'jdoe' })
|
|
|
|
* .update({ username: 'jdoe' })
|
|
|
|
* ```
|
|
|
|
* ```
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public query(): ModelBuilder<T> {
|
|
|
|
public query(): ModelBuilder<this> {
|
|
|
|
const ModelClass = this.constructor as typeof Model
|
|
|
|
const ModelClass = this.constructor as typeof Model
|
|
|
|
const builder = <ModelBuilder<T>> this.app().make<ModelBuilder<T>>(ModelBuilder, ModelClass)
|
|
|
|
const builder = <ModelBuilder<this>> this.app().make<ModelBuilder<this>>(ModelBuilder, ModelClass)
|
|
|
|
const source: QuerySource = ModelClass.querySource()
|
|
|
|
const source: QuerySource = ModelClass.querySource()
|
|
|
|
|
|
|
|
|
|
|
|
builder.connection(ModelClass.getConnection())
|
|
|
|
builder.connection(ModelClass.getConnection())
|
|
|
@ -352,6 +352,15 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
|
|
|
|
|
|
|
|
builder.withScopes(this.scopes)
|
|
|
|
builder.withScopes(this.scopes)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return this.newBuilderInstance(builder)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Configure ModelBuilder instances that query this model.
|
|
|
|
|
|
|
|
* @param builder
|
|
|
|
|
|
|
|
* @protected
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
protected newBuilderInstance(builder: ModelBuilder<this>): ModelBuilder<this> {
|
|
|
|
return builder
|
|
|
|
return builder
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -365,7 +374,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param key
|
|
|
|
* @param key
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static async findByKey<T2 extends Model<T2>>(key: ModelKey): Promise<undefined | T2> {
|
|
|
|
public static async findByKey<T2 extends Model>(this: StaticThis<T2, any[]> & typeof Model, key: ModelKey): Promise<undefined | T2> {
|
|
|
|
return this.query<T2>()
|
|
|
|
return this.query<T2>()
|
|
|
|
.where(this.qualifyKey(), '=', key)
|
|
|
|
.where(this.qualifyKey(), '=', key)
|
|
|
|
.limit(1)
|
|
|
|
.limit(1)
|
|
|
@ -376,7 +385,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Get an array of all instances of this model.
|
|
|
|
* Get an array of all instances of this model.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public async all(): Promise<T[]> {
|
|
|
|
public async all(): Promise<this[]> {
|
|
|
|
return this.query().get()
|
|
|
|
return this.query().get()
|
|
|
|
.all()
|
|
|
|
.all()
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -616,12 +625,12 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param withoutTimestamps
|
|
|
|
* @param withoutTimestamps
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public async save({ withoutTimestamps = false } = {}): Promise<Model<T>> {
|
|
|
|
public async save({ withoutTimestamps = false } = {}): Promise<this> {
|
|
|
|
await this.push(new ModelSavingEvent<T>(this as any))
|
|
|
|
await this.push(new ModelSavingEvent<this>(this))
|
|
|
|
const ctor = this.constructor as typeof Model
|
|
|
|
const ctor = this.constructor as typeof Model
|
|
|
|
|
|
|
|
|
|
|
|
if ( this.exists() && this.isDirty() ) {
|
|
|
|
if ( this.exists() && this.isDirty() ) {
|
|
|
|
await this.push(new ModelUpdatingEvent<T>(this as any))
|
|
|
|
await this.push(new ModelUpdatingEvent<this>(this))
|
|
|
|
|
|
|
|
|
|
|
|
if ( !withoutTimestamps && ctor.timestamps && ctor.UPDATED_AT ) {
|
|
|
|
if ( !withoutTimestamps && ctor.timestamps && ctor.UPDATED_AT ) {
|
|
|
|
(this as any)[ctor.UPDATED_AT] = new Date()
|
|
|
|
(this as any)[ctor.UPDATED_AT] = new Date()
|
|
|
@ -642,9 +651,9 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
await this.assumeFromSource(data)
|
|
|
|
await this.assumeFromSource(data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await this.push(new ModelUpdatedEvent<T>(this as any))
|
|
|
|
await this.push(new ModelUpdatedEvent<this>(this))
|
|
|
|
} else if ( !this.exists() ) {
|
|
|
|
} else if ( !this.exists() ) {
|
|
|
|
await this.push(new ModelCreatingEvent<T>(this as any))
|
|
|
|
await this.push(new ModelCreatingEvent<this>(this))
|
|
|
|
|
|
|
|
|
|
|
|
if ( !withoutTimestamps ) {
|
|
|
|
if ( !withoutTimestamps ) {
|
|
|
|
if ( ctor.timestamps && ctor.CREATED_AT ) {
|
|
|
|
if ( ctor.timestamps && ctor.CREATED_AT ) {
|
|
|
@ -675,10 +684,10 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
await this.assumeFromSource(data)
|
|
|
|
await this.assumeFromSource(data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await this.push(new ModelCreatedEvent<T>(this as any))
|
|
|
|
await this.push(new ModelCreatedEvent<this>(this))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await this.push(new ModelSavedEvent<T>(this as any))
|
|
|
|
await this.push(new ModelSavedEvent<this>(this))
|
|
|
|
return this
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -745,7 +754,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* This returns a NEW instance of the SAME record by matching on
|
|
|
|
* This returns a NEW instance of the SAME record by matching on
|
|
|
|
* the primary key. It does NOT change the current instance of the record.
|
|
|
|
* the primary key. It does NOT change the current instance of the record.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public async fresh(): Promise<Model<T> | undefined> {
|
|
|
|
public async fresh(): Promise<this | undefined> {
|
|
|
|
return this.query()
|
|
|
|
return this.query()
|
|
|
|
.where(this.qualifyKey(), '=', this.key())
|
|
|
|
.where(this.qualifyKey(), '=', this.key())
|
|
|
|
.limit(1)
|
|
|
|
.limit(1)
|
|
|
@ -789,7 +798,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param model
|
|
|
|
* @param model
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public async populate(model: T): Promise<T> {
|
|
|
|
public async populate(model: this): Promise<this> {
|
|
|
|
const row = this.toQueryRow()
|
|
|
|
const row = this.toQueryRow()
|
|
|
|
delete row[this.keyName()]
|
|
|
|
delete row[this.keyName()]
|
|
|
|
await model.assumeFromSource(row)
|
|
|
|
await model.assumeFromSource(row)
|
|
|
@ -803,7 +812,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param other
|
|
|
|
* @param other
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public is(other: Model<any>): boolean {
|
|
|
|
public is(other: Model): boolean {
|
|
|
|
return this.key() === other.key() && this.qualifyKey() === other.qualifyKey()
|
|
|
|
return this.key() === other.key() && this.qualifyKey() === other.qualifyKey()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -811,7 +820,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* Inverse of `is()`.
|
|
|
|
* Inverse of `is()`.
|
|
|
|
* @param other
|
|
|
|
* @param other
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public isNot(other: Model<any>): boolean {
|
|
|
|
public isNot(other: Model): boolean {
|
|
|
|
return !this.is(other)
|
|
|
|
return !this.is(other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -886,8 +895,8 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* @param foreignKeyOverride
|
|
|
|
* @param foreignKeyOverride
|
|
|
|
* @param localKeyOverride
|
|
|
|
* @param localKeyOverride
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public hasOne<T2 extends Model<T2>>(related: Instantiable<T2>, foreignKeyOverride?: keyof T & string, localKeyOverride?: keyof T2 & string): HasOne<T, T2> {
|
|
|
|
public hasOne<T2 extends Model>(related: Instantiable<T2>, foreignKeyOverride?: keyof this & string, localKeyOverride?: keyof T2 & string): HasOne<this, T2> {
|
|
|
|
return new HasOne<T, T2>(this as unknown as T, this.make(related), foreignKeyOverride, localKeyOverride)
|
|
|
|
return new HasOne<this, T2>(this, this.make(related), foreignKeyOverride, localKeyOverride)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -908,8 +917,8 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* @param foreignKeyOverride
|
|
|
|
* @param foreignKeyOverride
|
|
|
|
* @param localKeyOverride
|
|
|
|
* @param localKeyOverride
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public hasMany<T2 extends Model<T2>>(related: Instantiable<T2>, foreignKeyOverride?: keyof T & string, localKeyOverride?: keyof T2 & string): HasMany<T, T2> {
|
|
|
|
public hasMany<T2 extends Model>(related: Instantiable<T2>, foreignKeyOverride?: keyof this & string, localKeyOverride?: keyof T2 & string): HasMany<this, T2> {
|
|
|
|
return new HasMany<T, T2>(this as unknown as T, this.make(related), foreignKeyOverride, localKeyOverride)
|
|
|
|
return new HasMany<this, T2>(this, this.make(related), foreignKeyOverride, localKeyOverride)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -935,7 +944,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* @param related
|
|
|
|
* @param related
|
|
|
|
* @param relationName
|
|
|
|
* @param relationName
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public belongsToOne<T2 extends Model<T2>>(related: Instantiable<T>, relationName: keyof T2): HasOne<T, T2> {
|
|
|
|
public belongsToOne<T2 extends Model>(related: Instantiable<T2>, relationName: keyof T2): HasOne<this, T2> {
|
|
|
|
const relatedInst = this.make(related) as T2
|
|
|
|
const relatedInst = this.make(related) as T2
|
|
|
|
const relation = relatedInst.getRelation(relationName)
|
|
|
|
const relation = relatedInst.getRelation(relationName)
|
|
|
|
|
|
|
|
|
|
|
@ -946,11 +955,11 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
const localKey = relation.localKey
|
|
|
|
const localKey = relation.localKey
|
|
|
|
const foreignKey = relation.foreignKey
|
|
|
|
const foreignKey = relation.foreignKey
|
|
|
|
|
|
|
|
|
|
|
|
if ( !isKeyof(localKey, this as unknown as T) || !isKeyof(foreignKey, relatedInst) ) {
|
|
|
|
if ( !isKeyof(localKey, this) || !isKeyof(foreignKey, relatedInst) ) {
|
|
|
|
throw new TypeError('Local or foreign keys do not exist on the base model.')
|
|
|
|
throw new TypeError('Local or foreign keys do not exist on the base model.')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return new HasOne<T, T2>(this as unknown as T, relatedInst, localKey, foreignKey)
|
|
|
|
return new HasOne(this, relatedInst, localKey, foreignKey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -977,7 +986,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* @param related
|
|
|
|
* @param related
|
|
|
|
* @param relationName
|
|
|
|
* @param relationName
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public belongsToMany<T2 extends Model<T2>>(related: Instantiable<T>, relationName: keyof T2): HasMany<T, T2> {
|
|
|
|
public belongsToMany<T2 extends Model>(related: Instantiable<T2>, relationName: keyof T2): HasMany<this, T2> {
|
|
|
|
const relatedInst = this.make(related) as T2
|
|
|
|
const relatedInst = this.make(related) as T2
|
|
|
|
const relation = relatedInst.getRelation(relationName)
|
|
|
|
const relation = relatedInst.getRelation(relationName)
|
|
|
|
|
|
|
|
|
|
|
@ -988,11 +997,11 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
const localKey = relation.localKey
|
|
|
|
const localKey = relation.localKey
|
|
|
|
const foreignKey = relation.foreignKey
|
|
|
|
const foreignKey = relation.foreignKey
|
|
|
|
|
|
|
|
|
|
|
|
if ( !isKeyof(localKey, this as unknown as T) || !isKeyof(foreignKey, relatedInst) ) {
|
|
|
|
if ( !isKeyof(localKey, this) || !isKeyof(foreignKey, relatedInst) ) {
|
|
|
|
throw new TypeError('Local or foreign keys do not exist on the base model.')
|
|
|
|
throw new TypeError('Local or foreign keys do not exist on the base model.')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return new HasMany<T, T2>(this as unknown as T, relatedInst, localKey, foreignKey)
|
|
|
|
return new HasMany(this, relatedInst, localKey, foreignKey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1000,7 +1009,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
|
|
|
* @param name
|
|
|
|
* @param name
|
|
|
|
* @protected
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public getRelation<T2 extends Model<T2>>(name: keyof this): Relation<T, T2, RelationValue<T2>> {
|
|
|
|
public getRelation<T2 extends Model>(name: keyof this): Relation<this, T2, RelationValue<T2>> {
|
|
|
|
const relFn = this[name]
|
|
|
|
const relFn = this[name]
|
|
|
|
|
|
|
|
|
|
|
|
if ( relFn instanceof Relation ) {
|
|
|
|
if ( relFn instanceof Relation ) {
|
|
|
|