bookshelf.js equivalent of Rails default scope (in node.js)

987 Views Asked by At

Is there a bookshelf.js (http://bookshelfjs.org/) equivalent to the 'default scope' in Rails?

For example, lets say I have the model "User":

User = Knex.Model.extend({
  tableName: 'users'
});

Let's also say that the user's table has a boolean field called "verified". What I want to know is if there is a way to have a default scope such that when I query the users table,

collection.fetch().then(function(collection) {
  // the collection contains only users with the verified = true attribute
})

the collection returned contains only users with the verified = true attribute

4

There are 4 best solutions below

1
On BEST ANSWER

Bookshelf model (or any backbone model) allow extending both instance properties and classProperties.

classProperties attaches directly to the constructor function which is similar to ActiveRecord's scope methods.

You can add verified method to User model's class properties like this.

User = Bookshelf.Model.extend({
    tableName: 'users'
}, {

    verified:  function (options) {
        options = options || {};
        return Db.Collection.forge([], {model: this}).query(function (qb) {
            qb.where('verified', true);
        }).fetch(options);
    }

});

And use it like this.

User.verified().then(function(collection) {
  // the collection contains only users with the verified = true attribute
});
0
On

This is something on the roadmap, for now you can do something like:

collection.query('where', 'verified', '=', true).fetch().then(function(collection) {
  // the collection contains only users with the verified = true attribute
});
0
On

you could also simply cache the partial query like

var default_query = collection.query('where', 'verified', '=', true);

and then always use that, I guess?

0
On

I just build an NPM package that does this using a bookshelf plugin called bookshelf-scopes.

var knex = require('knex')({
  client: 'sqlite3',
  connection: { filename: "./mytestdb" }
});

var bookshelf = require('bookshelf')(knex);
bookshelf.plugin(require('bookshelf-scopes'));

Now in your model you can add scopes.

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