ModelRelation: add post-query filters

This commit is contained in:
Alice Gaudon 2020-07-27 10:56:10 +02:00
parent c32048e047
commit 2bbe4db5fe

View File

@ -6,6 +6,7 @@ export default abstract class ModelRelation<S extends Model, O extends Model, R
protected readonly model: S; protected readonly model: S;
protected readonly foreignFactory: ModelFactory<O>; protected readonly foreignFactory: ModelFactory<O>;
protected readonly query: ModelQuery<O>; protected readonly query: ModelQuery<O>;
protected readonly filters: ModelFilter<O>[] = [];
protected cachedModels?: R; protected cachedModels?: R;
protected constructor(model: S, foreignFactory: ModelFactory<O>) { protected constructor(model: S, foreignFactory: ModelFactory<O>) {
@ -21,6 +22,11 @@ export default abstract class ModelRelation<S extends Model, O extends Model, R
return this; return this;
} }
public filter(modelFilter: ModelFilter<O>): this {
this.filters.push(modelFilter);
return this;
}
public abstract getModelID(): any; public abstract getModelID(): any;
protected abstract async compute(query: ModelQuery<O>): Promise<R>; protected abstract async compute(query: ModelQuery<O>): Promise<R>;
@ -63,6 +69,18 @@ export class OneModelRelation<S extends Model, O extends Model> extends ModelRel
return await query.first(); return await query.first();
} }
public async get(): Promise<O | null> {
const model = await super.get();
if (model) {
for (const filter of this.filters) {
if (!(await filter(model))) {
return null;
}
}
}
return model;
}
public async eagerLoad(relations: ModelRelation<S, O, O | null>[]): Promise<ModelQueryResult<O>> { public async eagerLoad(relations: ModelRelation<S, O, O | null>[]): Promise<ModelQueryResult<O>> {
this.query.where( this.query.where(
this.dbProperties.foreignKey, this.dbProperties.foreignKey,
@ -103,6 +121,20 @@ export class ManyModelRelation<S extends Model, O extends Model> extends ModelRe
return await query.get(); return await query.get();
} }
public async get(): Promise<O[]> {
let models = await super.get();
for (const filter of this.filters) {
const newModels = [];
for (const model of models) {
if (await filter(model)) {
newModels.push(model);
}
}
models = newModels;
}
return models;
}
public async eagerLoad(relations: ModelRelation<S, O, O[]>[]): Promise<ModelQueryResult<O>> { public async eagerLoad(relations: ModelRelation<S, O, O[]>[]): Promise<ModelQueryResult<O>> {
this.query.where( this.query.where(
this.dbProperties.foreignKey, this.dbProperties.foreignKey,
@ -142,6 +174,20 @@ export class ManyThroughModelRelation<S extends Model, O extends Model> extends
return await query.get(); return await query.get();
} }
public async get(): Promise<O[]> {
let models = await super.get();
for (const filter of this.filters) {
const newModels = [];
for (const model of models) {
if (await filter(model)) {
newModels.push(model);
}
}
models = newModels;
}
return models;
}
public async eagerLoad(relations: ModelRelation<S, O, O[]>[]): Promise<ModelQueryResult<O>> { public async eagerLoad(relations: ModelRelation<S, O, O[]>[]): Promise<ModelQueryResult<O>> {
this.query.where( this.query.where(
`pivot.${this.dbProperties.localPivotKey}`, `pivot.${this.dbProperties.localPivotKey}`,
@ -163,6 +209,8 @@ export class ManyThroughModelRelation<S extends Model, O extends Model> extends
export type QueryModifier<M extends Model> = (query: ModelQuery<M>) => ModelQuery<M>; export type QueryModifier<M extends Model> = (query: ModelQuery<M>) => ModelQuery<M>;
export type ModelFilter<O extends Model> = (model: O) => boolean | Promise<boolean>;
export type RelationDatabaseProperties = { export type RelationDatabaseProperties = {
localKey: string; localKey: string;
foreignKey: string; foreignKey: string;