npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bookshelf-scopes

v1.5.1

Published

Giving you Rails like scopes in Bookshelf.js.

Downloads

1,058

Readme

Bookshelf-Scopes

CircleCI

Giving you Rails like scopes in Bookshelf.js. This was originally a PK4Media project but I moved it over to my account as they do not use it anymore.

If you add in the plugin like so:

var bookshelf = require('bookshelf')(knex);

bookshelf.plugin(require('bookshelf-scopes'));

You will then be able to add a scopes property on your models that will give you a Knex query builder as the first argument and then followed by any additional arguments. See examples below.

Also just like rails we can set a default. See examples below.

Examples

Simple

You can define a model with scopes and an active function like this:

var TestModel = bookshelf.Model.extend({
  tableName: 'testmodel',
  scopes: {
    active: function(qb) {
      qb.where({status: 'Active'});
    },
    nameContains: function(qb, name) {
      qb.where(knex.raw('name LIKE ?', '%' + name + '%'));
    }
  }
});

You can now run code like this to get all Active:

TestModel.active().fetchAll().then(function(allActiveTests) {
  ...
});

You can also get all active where name contains test as well:

TestModel.active().nameContains('test').fetchAll().then(function(allActiveTests) {
  ...
});

Default

You can define a model with scopes and default like this:

var TestModel = bookshelf.Model.extend({
  tableName: 'testmodel',
  scopes: {
    default: function(qb) {
      qb.where({archived: 0});
    }
  }
});

Now if you call fetchAll or fetch on any of your queries you will only get items that have archive set to 0:

TestModel.fetchAll().then(function(allUnArchived) {
  ...
});

If you need to query without the default scope you can call unscoped like so:

TestModel.unscoped().fetchAll().then(function(allModels) {
  ...
});

Combine Methods In Scope

You can define a bunch of scope functions you can also combine them in another scope function.

var TestModel = bookshelf.Model.extend({
  tableName: 'testmodel',
  scopes: {
    running: function(qb) {
      qb.where({running: 0});
    },
    byDate: function(qb, date) {
      qb.where('created_date', '>=', date);
    },
    runningByDate: function(qb, date) {
      this.running(qb);
      this.byDate(qb, date);
    }
  }
});

Now you can use the combined scope method as well to make things more readable.

TestModel.runningByDate('2015-01-01').fetchAll().then(function(allUnArchived) {
  ...
});

Scopes on Relationships

You can also use scopes in the relationships as well. So you could have a model like this:

var TestModel = bookshelf.Model.extend({
  tableName: 'testmodel',
  scopes: {
    active: function(qb) {
      qb.where('active', '=', true);
    }
  }
});

And then you can have a model that has many active models above as children like so:

var MyModel = bookshelf.Model.extend({
  tableName: 'mymodel',
  active_test_models: function() {
    return this.hasMany(TestModel1).active();
  }
});

Override Initialize

If in your model you set an initialize you will need to call addScope() to add default scope if you want it

var TestModel = bookshelf.Model.extend({
  tableName: 'testmodel',
  scopes: {
    default: function(qb) {
      qb.where({status: 'Active'});
    }
  },
  initialize: function() {
    this.addScope(); //Now default scope is set, all other scopes work regardless.
    this.newValue = 1;
  }
});

Then calls to fetchAll will include it.

TestModel.fetchAll().then(function(allActive) {
  ...
});