Skip to main content

scopes

The scoping system will be familiar to those coming from the Ruby on Rails camp, but for those who are new to this, our design was inspired by the Ruby on Rails scope pattern, and can be used to elegantly capture recurring query behavior into partialized functions which can then be applied to your queries, enabling your complex statements to be replaced with beautiful business logic.

All scope functions receive a Query<ClassName> (where ClassName is the name of the Dream class defining the Scope) instance and return a clone of that instance (usually by calling where on that instance):

export default class Post extends ApplicationModel {
...

@deco.Scope()
public static withFunnyName(query: Query<Post>) {
return query.where({ name: 'Chalupas jr' })
}
}

const posts = await Post.scope('withFunnyName').all()

Default scopes

While regular scopes are meant to be applied manually, default scopes will automatically be applied to all queries. This behavior should be used sparingly, but there are occasionally pretty good cases for it, as seen below, emulating the Ruby on Rails paranoid gem pattern:

export default class Post extends ApplicationModel {
...

@deco.Scope({ default: true })
public static hideDeleted(query: Query<Post>) {
return query.where({ deletedAt: null })
}
}

Built-in default scopes

Two default scopes are built into Dream and applied automatically — you don't declare either one yourself:

  • dream:SoftDelete — added by the @SoftDelete() decorator, hides records where deletedAt is not null. See destroying.
  • dream:STI — added by the @STI() decorator, restricts a child model's queries to rows of its own type. See single table inheritance.

An STI child of a soft-deletable parent carries both: the inherited dream:SoftDelete scope plus its own dream:STI scope.

Bypassing default scopes

Use removeDefaultScope('name') to bypass one named default scope — it leaves other default scopes (including any other model's default scopes reached through an association) in place. See removing default scopes for examples.