# Types

This page contains the documentation of all other types and classes than Model and QueryBuilder. There are two types of items on this page:

  1. type: A type is just a POJO (Plain Old Javascript Object) with a set of properties.
  2. class: A class is a JavaScript class with properties and methods.

# type RelationMapping

Property Type Description
relation function The relation type. One of Model.BelongsToOneRelation, Model.HasOneRelation, Model.HasManyRelation, Model.ManyToManyRelation and Model.HasOneThroughRelation.
modelClass Model
string
Constructor of the related model class, an absolute path to a module that exports one or a path relative to modelPaths that exports a model class.
join RelationJoin Describes how the models are related to each other. See RelationJoin.
modify function(QueryBuilder)
string
object
Optional modifier for the relation query. If specified as a function, it will be called each time before fetching the relation. If specified as a string, modifier with specified name will be applied each time when fetching the relation. If specified as an object, it will be used as an additional query parameter - e. g. passing {name: 'Jenny'} would additionally narrow fetched rows to the ones with the name 'Jenny'.
filter function(QueryBuilder)
string
object
Alias for modify.
beforeInsert function(ModelQueryContext) Optional insert hook that is called for each inserted model instance. This function can be async.

# type RelationJoin

Property Type Description
from string
ReferenceBuilder
Array
The relation column in the owner table. Must be given with the table name. For example persons.id. Composite key can be specified using an array of columns e.g. ['persons.a', 'persons.b']. Note that neither this nor to need to be foreign keys or primary keys. You can join any column to any column. You can even join nested json fields using the ref helper.
to string
ReferenceBuilder
Array
The relation column in the related table. Must be given with the table name. For example movies.id. Composite key can be specified using an array of columns e.g. ['movies.a', 'movies.b']. Note that neither this nor from need to be foreign keys or primary keys. You can join any column to any column. You can even join nested json fields using the ref helper.
through RelationThrough Describes the join table if the models are related through one.

# type RelationThrough

Property Type Description
from string
ReferenceBuilder
Array
The column that is joined to from property of the RelationJoin. For example Person_movies.actorId where Person_movies is the join table. Composite key can be specified using an array of columns e.g. ['persons_movies.a', 'persons_movies.b']. You can join nested json fields using the ref helper.
to string
ReferenceBuilder
Array
The column that is joined to to property of the RelationJoin. For example Person_movies.movieId where Person_movies is the join table. Composite key can be specified using an array of columns e.g. ['persons_movies.a', 'persons_movies.b']. You can join nested json fields using the ref helper.
modelClass string
ModelClass
If you have a model class for the join table, you should specify it here. This is optional so you don't need to create a model class if you don't want to.
extra string
string[]
Object
Join table columns listed here are automatically joined to the related objects when they are fetched and automatically written to the join table instead of the related table on insert and update. The values can be aliased by providing an object {propertyName: 'columnName', otherPropertyName: 'otherColumnName'} instead of array.
beforeInsert function(ModelQueryContext) Optional insert hook that is called for each inserted join table model instance. This function can be async.

# type ModelOptions

Property Type Description
patch boolean If true the json is treated as a patch and the required field of the json schema is ignored in the validation. This allows us to create models with a subset of required properties for patch operations.
skipValidation boolean If true the json schema validation is skipped
old object The old values for methods like $beforeUpdate and $beforeValidate.

# type CloneOptions

Property Type Description
shallow boolean If true, relations are ignored

# type ToJsonOptions

Property Type Description
shallow boolean If true, relations are ignored. Default is false.
virtuals boolean
string[]
If false, virtual attributes are omitted from the output. Default is true. You can also pass an array of property names and only those virtual properties get picked. You can even pass in property/function names that are not included in the static virtualAttributes array.

# type GraphOptions

Property Type Description
minimize boolean If true the aliases of the joined tables and columns created by withGraphJoined are minimized. This is sometimes needed because of identifier length limitations of some database engines. ExpressWeb JS throws an exception when a query exceeds the length limit. You need to use this only in those cases.
separator string Separator between relations in nested withGraphJoined query. Defaults to :. Dot (.) cannot be used at the moment because of the way knex parses the identifiers.
aliases Object Aliases for relations in a withGraphJoined query. Defaults to an empty object.
joinOperation string Which join type to use ['leftJoin', 'innerJoin', 'rightJoin', ...] or any other knex join method name. Defaults to leftJoin.
maxBatchSize integer For how many parents should a relation be fetched using a single query at a time. If you set this to 1 then a separate query is used for each parent to fetch a relation. For example if you want to fetch pets for 5 persons, you get five queries (one for each person). Setting this to 1 will allow you to use stuff like limit and aggregate functions in modifyGraph and other graph modifiers. This can be used to replace the naiveEager ExpressWeb JS 1.x had.

# type UpsertGraphOptions

Property Type Description
relate boolean
string[]
If true, relations are related instead of inserted. Relate functionality can be enabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
unrelate boolean
string[]
If true, relations are unrelated instead of deleted. Unrelate functionality can be enabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
insertMissing boolean
string[]
If true, models that have identifiers and are not found in the database, are inserted. By default this is false and an error is thrown. This functionality can be enabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
update boolean
string[]
If true, update operations are performed instead of patch when altering existing models, affecting the way the data is validated. With update operations, all required fields need to be present in the data provided. This functionality can be enabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
noInsert boolean
string[]
If true, no inserts are performed. Inserts can be disabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
noUpdate boolean
string[]
If true, no updates are performed. Updates can be disabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
noDelete boolean
string[]
If true, no deletes are performed. Deletes can be disabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
noRelate boolean
string[]
If true, no relates are performed. Relate operations can be disabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
noUnrelate boolean
string[]
If true, no unrelate operations are performed. Unrelate operations can be disabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
allowRefs boolean This needs to be true if you want to use #ref in your graphs. See this section for #ref usage examples.

# type InsertGraphOptions

Property Type Description
relate boolean
string[]
If true, models with an id are related instead of inserted. Relate functionality can be enabled for a subset of relations of the graph by providing a list of relation expressions. See the examples here.
allowRefs boolean This needs to be true if you want to use #ref in your graphs. See this section for #ref usage examples.

# type FetchGraphOptions

Property Type Description
transaction knex
Transaction
Optional transaction or knex instance for the query. This can be used to specify a transaction or even a different database.
skipFetched boolean If true, only fetch relations that don't yet exist in the object.

# type TableMetadataFetchOptions

Property Type Description
table string A custom table name. If not given, Model.tableName is used.
knex knex
Transaction
A knex instance or a transaction

# type TableMetadataOptions

Property Type Description
table string A custom table name. If not given, Model.tableName is used.

# type TableMetadata

Property Type Description
columns string[] Names of all the columns in a table.

# type StaticHookArguments

Property Type Description
items Model[] Items for which the query was started. For example in case of an instance query person.$query() or person.$relatedQuery('pets') items would equal [person]. In case of Person.relatedQuery('pets').for([matt, jennifer]) items would equal [matt, jennifer]. In many cases like Person.query() or Person.query().findById(1) this array is empty. It's only populated when the query has been explicitly started for a set of model instances.
inputItems Model[] Items that were passed as an input for the query. For example in case of Person.query().insert(person) or Person.query().patch(person) inputItems would equal [person].
asFindQuery () => QueryBuilder A function that returns a query builder that can be used to fetch the items that were/would get affected by the query being executed. Modifying this query builder doesn't affect the query being executed. For example calling await asFindQuery().select('id') in a beforeDelete hook would get you the identifiers of all the items that will get deleted by the query. This query is automatically executed inside any existing transaction. This query builder always returns an array even if the query being executed would return an object, a number or something else.
transaction knex
Transaction
If the query being executed has a transaction, this property will contain it. Otherwise this holds the knex instance installed for the query. Either way, this can and should be passed to any queries executed in the static hooks.
context object The context of the query. See context.
relation Relation If the query is for a relation, this property holds the Relation object. For example when you call person.$relatedQuery('pets) or Person.relatedQuery('movies') the relation will be a relation object for pets and movies relation of Person respectively.
cancelQuery function(any) Cancels the query being executed. You can pass an arugment for the function and that value will be the result of the query.

# type FieldExpression

Field expressions are strings that allow you to refer to JSONB fields inside columns.

Syntax: <column reference>[:<json field reference>]

e.g. persons.jsonColumnName:details.names[1] would refer to value 'Second' in column persons.jsonColumnName which has { details: { names: ['First', 'Second', 'Last'] } } object stored in it.

First part <column reference> is compatible with column references used in knex e.g. MyFancyTable.tributeToThBestColumnNameEver.

Second part describes a path to an attribute inside the referred column. It is optional and it always starts with colon which follows directly with first path element. e.g. Table.jsonObjectColumnName:jsonFieldName or Table.jsonArrayColumn:[321].

Syntax supports [<key or index>] and .<key or index> flavors of reference to json keys / array indexes:

e.g. both Table.myColumn:[1][3] and Table.myColumn:1.3 would access correctly both of the following objects [null, [null,null,null, "I was accessed"]] and { "1": { "3" : "I was accessed" } }

Caveats when using special characters in keys:

  1. objectColumn.key This is the most common syntax, good if you are not using dots or square brackets [] in your json object key name.
  2. Keys containing dots objectColumn:[keywith.dots] Column { "keywith.dots" : "I was referred" }
  3. Keys containing square brackets column['[]'] { "[]" : "This is getting ridiculous..." }
  4. Keys containing square brackets and quotes objectColumn:['Double."Quote".[]'] and objectColumn:["Sinlge.'Quote'.[]"] Column { "Double.\"Quote\".[]" : "I was referred", "Sinlge.'Quote'.[]" : "Mee too!" }
  5. Keys containing dots, square brackets, single quotes and double quotes in one json key is not currently supported

There are some special methods that accept FieldExpression strings directly, like whereJsonSupersetOf but you can use FieldExpressions anywhere with ref. Here's an example:

const { ref } = require("objection");

await Person.query()
  .select([
    "id",
    ref("persons.jsonColumn:details.name").castText().as("name"),
    ref("persons.jsonColumn:details.age").castInt().as("age"),
  ])
  .join(
    "someTable",
    ref("persons.jsonColumn:details.name").castText(),
    "=",
    ref("someTable.name")
  )
  .where("age", ">", ref("someTable.ageLimit"));
Copied!

In the above example, we assume persons table has a column named jsonColumn of type jsonb (only works on postgres).

# type RelationExpression

Relation expression is a simple DSL for expressing relation trees.

These strings are all valid relation expressions:

  • children
  • children.movies
  • [children, pets]
  • [children.movies, pets]
  • [children.[movies, pets], pets]
  • [children.[movies.actors.[children, pets], pets], pets]
  • [children as kids, pets(filterDogs) as dogs]

There are two tokens that have special meaning: * and ^. * means "all relations recursively" and ^ means "this relation recursively".

For example children.* means "relation children and all its relations, and all their relations and ...".

WARNING

The * token must be used with caution or you will end up fetching your entire database.

Expression parent.^ is equivalent to parent.parent.parent.parent... up to the point a relation no longer has results for the parent relation. The recursion can be limited to certain depth by giving the depth after the ^ character. For example parent.^3 is equal to parent.parent.parent.

Relations can be aliased using the as keyword.

For example the expression children.[movies.actors.[pets, children], pets] represents a tree:

              children
              (Person)
                 |
         -----------------
         |               |
       movies           pets
      (Movie)         (Animal)
         |
       actors
      (Person)
         |
    -----------
    |         |
   pets    children
 (Animal)  (Person)

Copied!

The model classes are shown in parenthesis. When given to withGraphFetched method, this expression would fetch all relations as shown in the tree above:

const people = await Person.query().withGraphFetched(
  "children.[movies.actors.[pets, children], pets]"
);

// All persons have the given relation tree fetched.
console.log(people[0].children[0].movies[0].actors[0].pets[0].name);
Copied!

Relation expressions can have arguments. Arguments are used to refer to modifier functions (either global or local. Arguments are listed in parenthesis after the relation names like this:

Person.query().withGraphFetched(
  `children(arg1, arg2).[movies.actors(arg3), pets]`
);
Copied!

You can spread relation expressions to multiple lines and add whitespace:

Person.query().withGraphFetched(`[
    children.[
      pets,
      movies.actors.[
        pets,
        children
      ]
    ]
  ]`);
Copied!

Relation expressions can be aliased using as keyword:

Person.query().withGraphFetched(`[
    children as kids.[
      pets(filterDogs) as dogs,
      pets(filterCats) as cats,

      movies.actors.[
        pets,
        children as kids
      ]
    ]
  ]`);
Copied!

# RelationExpression object notation

In addition to the string expressions, a more verbose object notation can also be used.

The string expression in the comment is equivalent to the object expression below it:

// `children`
{
  children: true;
}
Copied!
// `children.movies`
{
  children: {
    movies: true;
  }
}
Copied!
// `[children, pets]`
{
  children: true;
  pets: true;
}
Copied!
// `[children.[movies, pets], pets]`
{
  children: {
    movies: true,
    pets: true
  }
  pets: true
}
Copied!
// `parent.^`
{
  parent: {
    $recursive: true;
  }
}
Copied!
// `parent.^5`
{
  parent: {
    $recursive: 5;
  }
}
Copied!
// `parent.*`
{
  parent: {
    $allRecursive: true;
  }
}
Copied!
// `[children as kids, pets(filterDogs) as dogs]`
{
  kids: {
    $relation: 'children'
  },

  dogs: {
    $relation: 'pets',
    $modify: ['filterDogs']
  }
}
Copied!

# type TransactionObject

This is nothing more than a knex transaction object. It can be used as a knex query builder, it can be passed to ExpressWeb JS queries and models can be bound to it.

# Instance Methods

# commit()

const promise = trx.commit();
Copied!

Call this method to commit the transaction. This only needs to be called if you use transaction.start() method.

# rollback()

const promise = trx.rollback(error);
Copied!

Call this method to rollback the transaction. This only needs to be called if you use transaction.start() method. You need to pass the error to the method as the only argument.

# class ValidationError

const { ValidationError } = require("objection");

throw new ValidationError({ type, message, data });
Copied!

For each key, a list of errors is given. Each error contains the default message (as returned by the validator), an optional keyword string to identify the validation rule which didn't pass and a param object which optionally contains more details about the context of the validation error.

If type is anything else but "ModelValidation", data can be any object that describes the error.

Error of this class is thrown by default if validation of any input fails. By input we mean any data that can come from the outside world, like model instances (or POJOs), relation expressions object graphs etc.

You can replace this error by overriding Model.createValidationError() method.

Property Type Description
statusCode number HTTP status code for interop with express error handlers and other libraries that search for status code from errors.
type string One of "ModelValidation", "RelationExpression", "UnallowedRelation" and "InvalidGraph". This can be any string for your own custom errors. The listed values are used internally by ExpressWeb JS.
data object The content of this property is documented below for "ModelValidation" errors. For other types, this can be any data.

If type is "ModelValidation" then data object should follow this pattern:

{
  key1: [{
    message: '...',
    keyword: 'required',
    params: null
  }, {
    message: '...',
    keyword: '...',
    params: {
      ...
    }
  }, ...],

  key2: [{
    message: '...',
    keyword: 'minLength',
    params: {
      limit: 1,
      ...
    }
  }, ...],

  ...
}
Copied!

# class NotFoundError

const { NotFoundError } = require("objection");

throw new NotFoundError(data);
Copied!

Error of this class is thrown by default by throwIfNotFound()

You can replace this error by overriding Model.createNotFoundError() method.

# class Relation

Relation is a parsed and normalized instance of a RelationMapping. Relations can be accessed using the getRelations method.

Relation holds a RelationProperty instance for each property that is used to create the relationship between two tables.

Relation is actually a base class for all relation types BelongsToOneRelation, HasManyRelation etc. You can use instanceof to determine the type of the relations (see the example on the right). Note that HasOneRelation is a subclass of HasManyRelation and HasOneThroughRelation is a subclass of ManyToManyRelation. Arrange your instanceof checks accordingly.

Property Type Description
name string Name of the relation. For example pets or children.
ownerModelClass function The model class that has defined the relation.
relatedModelClass function The model class of the related objects.
ownerProp RelationProperty The relation property in the ownerModelClass.
relatedProp RelationProperty The relation property in the relatedModelClass.
joinModelClass function The model class representing the join table. This class is automatically generated by ExpressWeb JS if none is provided in the join.through.modelClass setting of the relation mapping, see RelationThrough.
joinTable string The name of the join table (only for ManyToMany and HasOneThrough relations).
joinTableOwnerProp RelationProperty The join table property pointing to ownerProp (only for ManyToMany and HasOneThrough relations).
joinTableRelatedProp RelationProperty The join table property pointing to relatedProp (only for ManyToMany and HasOneThrough relations).

Note that Relation instances are actually instances of the relation classes used in relationMappings. For example:

class Person extends Model {
  static get relationMappings() {
    return {
      pets: {
        relation: Model.HasManyRelation,
        modelClass: Animal,
        join: {
          from: "persons.id",
          to: "animals.ownerId",
        },
      },
    };
  }
}

const relations = Person.getRelations();

console.log(relations.pets instanceof Model.HasManyRelation); // --> true
console.log(relations.pets.name); // --> pets
console.log(relations.pets.ownerProp.cols); // --> ['id']
console.log(relations.pets.relatedProp.cols); // --> ['ownerId']
Copied!

# class RelationProperty

Represents a property that is used to create relationship between two tables. A single RelationProperty instance can represent composite key. In addition to a table column, A RelationProperty can represent a nested field inside a column (for example a jsonb column).

# Properties

Property Type Description
size number The number of columns. In case of composite key, this is greater than one.
modelClass function The model class that owns the property.
props string[] The column names converted to "external" format. For example if modelClass defines a snake_case to camelCase conversion, these names are in camelCase. Note that a RelationProperty may actually point to a sub-properties of the columns in case they are of json or some other non-scalar type. This array always contains only the converted column names. Use getProp(obj, idx) method to get the actual value from an object.
cols string[] The column names in the database format. For example if modelClass defines a snake_case to camelCase conversion, these names are in snake_case. Note that a RelationProperty may actually point to a sub-properties of the columns in case they are of json or some other non-scalar type. This array always contains only the column names.

# Methods

# getProp()

const value = property.getProp(obj, index);
Copied!

Gets this property's index:th value from an object. For example if the property represents a composite key [a, b.d.e, c] and obj is {a: 1, b: {d: {e: 2}}, c: 3} then getProp(obj, 1) would return 2.

# setProp()

property.setProp(obj, index, value);
Copied!

Sets this property's index:th value in an object. For example if the property represents a composite key [a, b.d.e, c] and obj is {a: 1, b: {d: {e: 2}}, c: 3} then setProp(obj, 1, 'foo') would mutate obj into {a: 1, b: {d: {e: 'foo'}}, c: 3}.

# fullCol()

const col = property.fullCol(builder, index);
Copied!

Returns the property's index:th column name with the correct table reference. Something like "Table.column". The first argument must be an ExpressWeb JS QueryBuilder instance.

# ref()

const ref = property.ref(builder, index);
Copied!

Allows you to do things like this:

const builder = Person.query();
const ref = property.ref(builder, 0);
builder.where(ref, ">", 10);
Copied!

Returns a ReferenceBuilder instance that points to the index:th column.

# patch()

property.patch(patchObj, index, value);
Copied!

Allows you to do things like this:

const builder = Person.query();
const patch = {};
property.patch(patch, 0, "foo");
builder.patch(patch);
Copied!

Appends an update operation for the index:th column into patchObj object.

# class ReferenceBuilder

An instance of this is returned from the ref helper function.

# Instance Methods

# castText()

Cast reference to sql type text.

# castInt()

Cast reference to sql type integer.

# castBigInt()

Cast reference to sql type bigint.

# castFloat()

Cast reference to sql type float.

# castDecimal()

Cast reference to sql type decimal.

# castReal()

Cast reference to sql type real.

# castBool()

Cast reference to sql type boolean.

# castType()

Give custom type to which referenced value is cast to.

DEPRECATED: Use castTo instead. castType Will be removed in 2.0.

.castType('mytype') --> CAST(?? as mytype)

# castTo()

Give custom type to which referenced value is cast to.

.castTo('mytype') --> CAST(?? as mytype)

# castJson()

In addition to other casts wrap reference to_jsonb() function so that final value reference will be json type.

# as()

Gives an alias for the reference .select(ref('age').as('yougness'))

# from()

Specifies that table of the reference.

# class ValueBuilder

An instance of this is returned from the val helper function. If an object is given as a value, it is cast to json by default.

# Instance Methods

# castText()

Cast to sql type text.

# castInt()

Cast to sql type integer.

# castBigInt()

Cast to sql type bigint.

# castFloat()

Cast to sql type float.

# castDecimal()

Cast to sql type decimal.

# castReal()

Cast to sql type real.

# castBool()

Cast to sql type boolean.

# castTo()

Give custom type to which referenced value is cast to.

.castTo('mytype') --> CAST(?? as mytype)

# castJson()

Converts the value to json (jsonb in case of postgresql). The default cast type for object values.

# asArray()

Converts the value to an array.

val([1, 2, 3]).asArray() --> ARRAY[?, ?, ?]

Can be used in conjuction with castTo.

val([1, 2, 3]).asArray().castTo('real[]') -> CAST(ARRAY[?, ?, ?] AS real[])

# as()

Gives an alias for the reference .select(ref('age').as('yougness'))

# class RawBuilder

An instance of this is returned from the raw helper function.

# Instance Methods

# as()

Gives an alias for the raw expression .select(raw('concat(foo, bar)').as('fooBar')).

You should use this instead of inserting the alias to the SQL to give ExpressWeb JS more information about the query. Some edge cases, like using raw in select inside a withGraphJoined modifier won't work unless you use this method.

# class FunctionBuilder

An instance of this is returned from the fn helper function.

# Instance Methods

# as()

Gives an alias for the raw expression .select(fn('concat', 'foo', 'bar').as('fooBar')).

You should use this instead of inserting the alias to the SQL to ExpressWeb JS more information about the query. Some edge cases, like using fn in select inside a withGraphJoined modifier won't work unless you use this method.

# class Validator

const { Validator } = require("objection");
Copied!

Abstract class from which model validators must be inherited. See the example for explanation. Also check out the createValidator method.

# Examples

const { Validator } = require("objection");

class MyCustomValidator extends Validator {
  validate(args) {
    // The model instance. May be empty at this point.
    const model = args.model;

    // The properties to validate. After validation these values will
    // be merged into `model` by objection.
    const json = args.json;

    // `ModelOptions` object. If your custom validator sets default
    // values, you need to check the `opt.patch` boolean. If it is true
    // we are validating a patch object and the defaults should not be set.
    const opt = args.options;

    // A context object shared between the validation methods. A new
    // object is created for each validation operation. You can store
    // any data here.
    const ctx = args.ctx;

    // Do your validation here and throw any exception if the
    // validation fails.
    doSomeValidationAndThrowIfFails(json);

    // You need to return the (possibly modified) json.
    return json;
  }

  beforeValidate(args) {
    // Takes the same arguments as `validate`. Usually there is no need
    // to override this.
    return super.beforeValidate(args);
  }

  afterValidate(args) {
    // Takes the same arguments as `validate`. Usually there is no need
    // to override this.
    return super.afterValidate(args);
  }
}

const { Model } = require("objection");

// Override the `createValidator` method of a `Model` to use the
// custom validator.
class BaseModel extends Model {
  static createValidator() {
    return new MyCustomValidator();
  }
}
Copied!

# class AjvValidator

const { AjvValidator } = require("objection");
Copied!

The default Ajv (opens new window) based json schema validator. You can override the createValidator method of Model like in the example to modify the validator.

# Examples

const { Model, AjvValidator } = require("objection");

class BaseModel extends Model {
  static createValidator() {
    return new AjvValidator({
      onCreateAjv: (ajv) => {
        // Here you can modify the `Ajv` instance.
      },
      options: {
        allErrors: true,
        validateSchema: false,
        ownProperties: true,
        v5: true,
      },
    });
  }
}
Copied!