Objection.js: type issues with $relatedQuery and extended querybuilder

Created on 19 Jan 2020  路  2Comments  路  Source: Vincit/objection.js

extending the query builder with some method (like described in the docs) will still return the default querybuilder when calling $relatedQuery on an instance.

class MyQueryBuilder<M extends Model, R = M[]> extends QueryBuilder<M, R> {
  ArrayQueryBuilderType!: MyQueryBuilder<M, M[]>;
  SingleQueryBuilderType!: MyQueryBuilder<M, M>;
  NumberQueryBuilderType!: MyQueryBuilder<M, number>;
  PageQueryBuilderType!: MyQueryBuilder<M, Page<M>>;

  feed({page, size, where, orderBy, whereIn, whereNot}) {
    return this.skipUndefined()
    .where(where).orderBy([orderBy]).whereIn(whereIn?.column, whereIn?.values).whereNot(whereNot).page(page, size)
  }
}
class BaseModel extends Model {
  id!: number
  created_at?: string;
  updated_at?: string;
  QueryBuilderType!: MyQueryBuilder<this>;
  static QueryBuilder = MyQueryBuilder;
}

$relatedQuery will return QueryBuilder

article.$relatedQuery('revisions').feed({page, size, where, orderBy, whereIn, whereNot})

$query will return MyQueryBuilder

article.$query().feed({page, size, where, orderBy, whereIn, whereNot})

Most helpful comment

Thank you for your fast response.
You are right, it works. The Issue was a missing class property.
Keep up the good work :)

```js
import { Model, Page, QueryBuilder } from 'objection';

class MyQueryBuilder {
ArrayQueryBuilderType!: MyQueryBuilder SingleQueryBuilderType!: MyQueryBuilder;
NumberQueryBuilderType!: MyQueryBuilder;
PageQueryBuilderType!: MyQueryBuilder>;

myCustomMethod(): this {
    return this;
}

}

class BaseModel extends Model {
// Both of these are needed.
QueryBuilderType!: MyQueryBuilder;
static QueryBuilder = MyQueryBuilder;
}

class Pet extends BaseModel {
static tableName = 'pets';
}

class Person extends BaseModel {
static tableName = 'persons';

pets: Pet[] //needed or $relatedQuery wont work

static relationMappings = () => ({
    pets: {
        relation: BaseModel.HasManyRelation,
        modelClass: require('Pet'),
        join: {
            from: 'person.id',
            to: 'pet.ownerId'
        }
    },
})

}

const test = async () => {
const person = await Person.query().findById(1);

const pets = person.$relatedQuery('pets').myCustomMethod()

}

````

All 2 comments

No it won't if you also inherit the related model from BaseModel.

Thank you for your fast response.
You are right, it works. The Issue was a missing class property.
Keep up the good work :)

```js
import { Model, Page, QueryBuilder } from 'objection';

class MyQueryBuilder {
ArrayQueryBuilderType!: MyQueryBuilder SingleQueryBuilderType!: MyQueryBuilder;
NumberQueryBuilderType!: MyQueryBuilder;
PageQueryBuilderType!: MyQueryBuilder>;

myCustomMethod(): this {
    return this;
}

}

class BaseModel extends Model {
// Both of these are needed.
QueryBuilderType!: MyQueryBuilder;
static QueryBuilder = MyQueryBuilder;
}

class Pet extends BaseModel {
static tableName = 'pets';
}

class Person extends BaseModel {
static tableName = 'persons';

pets: Pet[] //needed or $relatedQuery wont work

static relationMappings = () => ({
    pets: {
        relation: BaseModel.HasManyRelation,
        modelClass: require('Pet'),
        join: {
            from: 'person.id',
            to: 'pet.ownerId'
        }
    },
})

}

const test = async () => {
const person = await Person.query().findById(1);

const pets = person.$relatedQuery('pets').myCustomMethod()

}

````

Was this page helpful?
0 / 5 - 0 ratings