@yadah/objection-scope

0.2.0 • Public • Published

Objection scope mixin

A mixin for Objection.js which extends the QueryBuilder to have a scope() method. It allows a model to define common query building functions based on a criteria object with a well-defined shape.

Usage

The Model.scopes object maps criteria keys to functions that work in a similar way to Model.modifiers. Scope modifiers accept the query object and the criteria object that was passed to the QueryBuilder.scope() function (this object will have a property with key that matches the Model.scopes key).

import ScopeMixin from "@yadah/objection-scope"
import { mixin, Model } from "objection"

class MyModel extends mixin(Model, [ScopeMixin]) {
  static get scopes() {
    return {
      ...super.scopes,
      keyword: (query, { keyword }) {
        return query.where("title", "like", `%${keyword}`)
      }
    }
  }
}

MyModel.query().scope({ keyword: "abc" })
// select * from "tableName" where "tableName"."title" like ?
// bindings: ["%abc"]

Matcher

The ScopeBuilder class can be used to help write common modifier patterns.

class MyModel extends mixin(Model, [ScopeMixin]) {
  static get scopes() {
    const matcher = new this.ScopeBuilder();
    return {
      ...super.scopes,
      field1: matcher,
      field2: matcher,
    };
  }
}
MyModel.query().scope({ field1: "foo", field2: "bar" });
// select * from "tableName" where "tableName"."field1" = ? and "tableName"."field2" = ?
// bindings: ["foo", "bar"]

The matcher object can be chained to produce various common types of query modifier.

const matcher = new this.ScopeBuilder();
const scopes = {
  field1: matcher,
  minField2: matcher.min,
  maxField3: matcher.max,
  field4: matcher.related("related"),
  field5: matcher.notNull,
};
Expression Result Notes
matcher .where(fieldName, value) if value is not an array
matcher .whereIn(fieldName, value) if value is an array
matcher.min .where(fieldName, ">=", value)
matcher.max .where(fieldname, "<=", value)
matcher.related(relationName) .joinRelated(relationName).where(`${relationName}.${fieldName}`, value) if value is not an array
matcher.related(relationName) .joinRelated(relationName).whereIn(`${relationName}.${fieldName}`, value) if value is an array
matcher.exists .whereExists(Model.relatedQuery(fieldName).scope(value))
matcher.notNull .whereNotNull(fieldname) if value is true
matcher.notNull .whereNull(fieldName) if value is false
matcher.name(name) changes fieldName to name

Readme

Keywords

Package Sidebar

Install

npm i @yadah/objection-scope

Weekly Downloads

0

Version

0.2.0

License

ISC

Unpacked Size

12.1 kB

Total Files

7

Last publish

Collaborators

  • ttoohey