From bd1c221e363199e360bfbdfe687d02ae7101b803 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Sun, 16 Aug 2020 09:46:17 -0500 Subject: [PATCH] Create belongs_to_one and belongs_to_many inverse helpers --- app/index.ts | 6 +++++- app/models/LoginAttempt.model.ts | 7 +++++++ orm/src/model/Model.ts | 33 ++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/app/index.ts b/app/index.ts index c628bc9..a9b7b77 100755 --- a/app/index.ts +++ b/app/index.ts @@ -29,6 +29,10 @@ console.log(sel.clone()) const gm = await sel.results().first() console.log(gm) -console.log(await gm.login_attempts()) + +const la = (await gm.login_attempts()).first() +console.log(la) + +console.log(await la.user()) // console.log(await las.fetchRelated()) diff --git a/app/models/LoginAttempt.model.ts b/app/models/LoginAttempt.model.ts index 96fc409..6ef3867 100644 --- a/app/models/LoginAttempt.model.ts +++ b/app/models/LoginAttempt.model.ts @@ -1,6 +1,8 @@ import {Model} from '../../orm/src/model/Model.ts' import {Field} from '../../orm/src/model/Field.ts' import {Type} from '../../orm/src/db/types.ts' +import UserModel from "./User.model.ts"; +import {Relation} from "../../orm/src/model/relation/decorators.ts"; export default class LoginAttemptModel extends Model { protected static table = 'daton_login_attempts' @@ -17,4 +19,9 @@ export default class LoginAttemptModel extends Model { @Field(Type.timestamp) protected attempt_date!: Date + + @Relation() + public user() { + return this.belongs_to_one(UserModel, 'login_attempts') + } } diff --git a/orm/src/model/Model.ts b/orm/src/model/Model.ts index 1d43b8e..1bddb69 100644 --- a/orm/src/model/Model.ts +++ b/orm/src/model/Model.ts @@ -17,6 +17,7 @@ import Instantiable from '../../../di/src/type/Instantiable.ts' import {HasMany} from './relation/HasMany.ts' import {ModelSelect} from "./query/ModelSelect.ts"; import {Relation} from "./relation/Relation.ts"; +import {HasOneOrMany} from "./relation/HasOneOrMany.ts"; // TODO separate read/write connections // TODO manual dirty flags @@ -979,6 +980,38 @@ abstract class Model> extends Builder implements Rehydrata return new HasMany(this as any, new related() as any, foreign_key, local_key) } + /** + * Defines the inverse of a has one or many relation. + * @param {typeof Model} related + * @param {string} relation_name - the name of the relation function on the inverse + */ + public belongs_to_one>(related: Instantiable, relation_name: string) { + const related_inst = new related() + const relation = related_inst.get_relation(relation_name) + + if ( !(relation instanceof HasOneOrMany) ) { + throw new TypeError(`Cannot create belongs to one relation. Inverse relation must be has one or many.`) + } + + return new HasOne(this as any, related_inst, relation.local_key, relation.foreign_key) + } + + /** + * Defines the inverse of a has one or many relation. + * @param {typeof Model} related + * @param {string} relation_name - the name of the relation function on the inverse + */ + public belongs_to_many>(related: Instantiable, relation_name: string) { + const related_inst = new related() + const relation = related_inst.get_relation(relation_name) + + if ( !(relation instanceof HasOneOrMany) ) { + throw new TypeError(`Cannot create belongs to one relation. Inverse relation must be has one or many.`) + } + + return new HasMany(this as any, related_inst, relation.local_key, relation.foreign_key) + } + public get_relation>(name: string): Relation { // @ts-ignore const rel: any = this[name]()