API Reference

Bookshelf

The Bookshelf library is initialized by passing an initialized Knex client instance. The knex documentation provides a number of examples for different databases.

Construction

new Bookshelf(knex) source

Parameters
  • knex Knex

    Knex instance.

Members

bookshelf.knex :Knex source

A reference to the Knex.js instance being used by Bookshelf.

Methods

bookshelf.plugin(plugin, options) source

Parameters
  • plugin string|array|function

    The plugin or plugins to add. If you provide a string it can represent a built-in plugin, an npm package or a file somewhere on your project. You can also pass a function as argument to add it as a plugin. Finally, it's also possible to pass an array of strings or functions to add them all at once.

  • options mixed

    This can be anything you want and it will be passed directly to the plugin as the second argument when loading it.

This method provides a nice, tested, standardized way of adding plugins to a Bookshelf instance, injecting the current instance into the plugin, which should be a module.exports.

You can add a plugin by specifying a string with the name of the plugin to load. In this case it will try to find a module. It will first check for a match within the bookshelf/plugins directory. If nothing is found it will pass the string to require(), so you can either require an npm dependency by name or one of your own modules by relative path:

bookshelf.plugin('./bookshelf-plugins/my-favourite-plugin');
bookshelf.plugin('plugin-from-npm');

There are a few built-in plugins already, along with many independently developed ones. See the list of available plugins.

You can also provide an array of strings or functions, which is the same as calling bookshelf.plugin() multiple times. In this case the same options object will be reused:

  bookshelf.plugin(['registry', './my-plugins/special-parse-format']);

Example plugin:

// Converts all string values to lower case when setting attributes on a model
module.exports = function(bookshelf) {
  bookshelf.Model = bookshelf.Model.extend({
    set: function(key, value, options) {
      if (!key) return this;
      if (typeof value === 'string') value = value.toLowerCase();
      return bookshelf.Model.prototype.set.call(this, key, value, options);
    }
  });
}

bookshelf.transaction(transactionCallback) → Promise source

Parameters
Returns
Promise

A promise resolving to the value returned from transactionCallback.

An alias to Knex#transaction, the transaction object must be passed along in the options of any relevant Bookshelf calls, to ensure all queries are on the same connection. The entire transaction block is a promise that will resolve when the transaction is committed, or fail if the transaction is rolled back.

When fetching inside a transaction it's possible to specify a row-level lock by passing the wanted lock type in the lock option to fetch. Available options are forUpdate and forShare.

var Promise = require('bluebird');

Bookshelf.transaction(function(t) {
  return new Library({name: 'Old Books'})
    .save(null, {transacting: t})
    .tap(function(model) {
      return Promise.map([
        {title: 'Canterbury Tales'},
        {title: 'Moby Dick'},
        {title: 'Hamlet'}
      ], function(info) {
        // Some validation could take place here.
        return new Book(info).save({'shelf_id': model.id}, {transacting: t});
      });
    });
}).then(function(library) {
  console.log(library.related('books').pluck('title'));
}).catch(function(err) {
  console.error(err);
});

Type Definitions

transactionCallback(transaction) → Promise source

Parameters
  • transaction Transaction
See
Returns
Promise

A transaction block to be provided to Bookshelf#transaction.

Model

Models are simple objects representing individual database rows, specifying the tableName and any relations to other models. They can be extended with any domain-specific methods, which can handle components such as validations, computed properties, and access control.

Construction

new Model(attributes, [options]) source

Parameters
  • attributes Object

    Initial values for this model's attributes.

  • [options] Object

    Hash of options.

    • [tableName] string

      Initial value for tableName.

    • [hasTimestamps=false] Boolean

      Initial value for hasTimestamps.

    • [parse=false] Boolean

      Convert attributes by parse before being set on the model.

When creating an instance of a model, you can pass in the initial values of the attributes, which will be set on the model. If you define an initialize function, it will be invoked when the model is created.

new Book({
  title: "One Thousand and One Nights",
  author: "Scheherazade"
});

In rare cases, if you're looking to get fancy, you may want to override constructor, which allows you to replace the actual constructor function for your model.

let Book = bookshelf.Model.extend({
  tableName: 'documents',
  constructor: function() {
    bookshelf.Model.apply(this, arguments);
    this.on('saving', function(model, attrs, options) {
      options.query.where('type', '=', 'book');
    });
  }
});

model.initialize(attributes, [options]) source

Parameters
  • attributes Object

    Initial values for this model's attributes.

  • [options] Object

    The hash of options passed to constructor.

See

Called by the Model constructor when creating a new instance. Override this function to add custom initialization, such as event listeners. Because plugins may override this method in subclasses, make sure to call your super (extended) class. e.g.

initialize: function() {
    this.constructor.__super__.initialize.apply(this, arguments);
    // Your initialization code ...
}

Static

Model.collection([models], [options])Collection source

Example
Customer.collection().fetch().then(function(collection) {
  // ...
});
Parameters
  • [models] Model[]
  • [options] Object
Returns
Collection

A simple static helper to instantiate a new Collection, setting the current model as the collection's target.

Model.count([column], [options]) → Promise source

Parameters
  • [column='*'] string

    Specify a column to count - rows with null values in this column will be excluded.

  • [options] Object

    Hash of options.

Since
  • 0.8.2
Returns
Promise

A promise resolving to the number of matching rows.

Gets the number of matching records in the database, respecting any previous calls to query. If a column is provided, records with a null value in that column will be excluded from the count.

Model.extend([prototypeProperties], [classProperties]) → function source

Parameters
  • [prototypeProperties] Object

    Instance methods and properties to be attached to instances of the new class.

  • [classProperties] Object

    Class (ie. static) functions and properties to be attached to the constructor of the new class.

Returns
function

Constructor for new Model subclass.

To create a Model class of your own, you extend bookshelf.Model.

extend correctly sets up the prototype chain, so subclasses created with extend can be further extended and subclassed as far as you like.

var checkit  = require('checkit');
var Promise  = require('bluebird');
var bcrypt   = Promise.promisifyAll(require('bcrypt'));

var Customer = bookshelf.Model.extend({
  initialize: function() {
    this.constructor.__super__.initialize.apply(this, arguments);
    this.on('saving', this.validateSave);
  },

  validateSave: function() {
    return checkit(rules).run(this.attributes);
  },

  account: function() {
    return this.belongsTo(Account);
  },
}, {
  login: Promise.method(function(email, password) {
    if (!email || !password) throw new Error('Email and password are both required');
    return new this({email: email.toLowerCase().trim()}).fetch({require: true}).tap(function(customer) {
      return bcrypt.compareAsync(password, customer.get('password'))
        .then(function(res) {
          if (!res) throw new Error('Invalid password');
        });
    });
  })
});

Customer.login(email, password)
  .then(function(customer) {
    res.json(customer.omit('password'));
  }).catch(Customer.NotFoundError, function() {
    res.json(400, {error: email + ' not found'});
  }).catch(function(err) {
    console.error(err);
  });

Brief aside on super: JavaScript does not provide a simple way to call super — the function of the same name defined higher on the prototype chain. If you override a core function like set, or save, and you want to invoke the parent object's implementation, you'll have to explicitly call it, along these lines:

var Customer = bookshelf.Model.extend({
  set: function() {
    // ...
    bookshelf.Model.prototype.set.apply(this, arguments);
    // ...
  }
});

Model.fetchAll() → Promise<Collection> source

See
Returns
Promise<Collection>

Simple helper function for retrieving all instances of the given model.

Model.forge([attributes], [options]) source

Parameters
  • [attributes] Object

    Initial values for this model's attributes.

  • [options] Object

    Hash of options.

    • [tableName] string

      Initial value for tableName.

    • [hasTimestamps=false] Boolean

      Initial value for hasTimestamps.

    • [parse=false] Boolean

      Convert attributes by parse before being set on the model.

A simple helper function to instantiate a new Model without needing new.

Members

model.defaults :Object|Null source

Example
var MyModel = bookshelf.Model.extend({
  defaults: {property1: 'foo', property2: 'bar'},
  tableName: 'my_table'
})

MyModel.forge({property1: 'blah'}).save().then(function(model) {
  // {property1: 'blah', property2: 'bar'}
})

This can be used to define any default values for attributes that are not present when creating or updating a model in a save call. The default behavior is to not use these default values on updates unless the defaults: true option is passed to the save call. For inserts the default values will always be used if present.

model.hasTimestamps :Boolean|Array source

Example
var MyModel = bookshelf.Model.extend({
  hasTimestamps: true,
  tableName: 'my_table'
})

var myModel = MyModel.forge({name: 'blah'}).save().then(function(savedModel) {
  // {
  //   name: 'blah',
  //   created_at: 'Sun Mar 25 2018 15:07:11 GMT+0100 (WEST)',
  //   updated_at: 'Sun Mar 25 2018 15:07:11 GMT+0100 (WEST)'
  // }
})

myModel.save({created_at: new Date(2015, 5, 2)}).then(function(updatedModel) {
  // {
  //   name: 'blah',
  //   created_at: 'Tue Jun 02 2015 00:00:00 GMT+0100 (WEST)',
  //   updated_at: 'Sun Mar 25 2018 15:07:11 GMT+0100 (WEST)'
  // }
})

Automatically sets the current date and time on the timestamp attributes created_at and updated_at based on the type of save method. The update method will only update updated_at, while the insert method will set both values.

To override the default attribute names, assign an array to this property. The first element will be the created column name and the second will be the updated one. If any of these elements is set to null that particular timestamp attribute will not be used in the model. For example, to automatically update only the created_at attribute set this property to ['created_at', null].

You can override the timestamp attribute values of a model and those values will be used instead of the automatic ones when saving.

model.idAttribute :string source

This tells the model which attribute to expect as the unique identifier for each database row (typically an auto-incrementing primary key named 'id'). Note that if you are using parse and format (to have your model's attributes in camelCase, but your database's columns in snake_case, for example) this refers to the name returned by parse (myId), not the actual database column (my_id).

You can also get the parsed id attribute value by using the model's parsedIdAttribute method.

If the table you're working with does not have a Primary-Key in the form of a single column you'll have to override it with a getter that returns null. Overriding with undefined does not cascade the default behavior of the value 'id'. Such a getter in ES6 would look like get idAttribute() { return null }.

model.processors :Boolean|Object source

An object mapping attribute names to one or more processor functions to apply to that attribute. By default the value of this property is false to indicate that this model doesn't have any processors set.

model.tableName :string source

Example
var Television = bookshelf.Model.extend({
  tableName: 'televisions'
});

A required property for any database usage, The tableName property refers to the database table name the model will query against.

Methods

model.belongsTo(Target, [foreignKey], [foreignKeyTarget])Model source

Parameters
  • Target Model

    Constructor of Model targeted by join.

  • [foreignKey] string

    ForeignKey in this model. By default, the foreignKey is assumed to be the singular form of the Target model's tableName, followed by _id / _{{idAttribute}}.

  • [foreignKeyTarget] string

    Column in the Target model's table which foreignKey references, if other than Target model's id / idAttribute.

Returns
Model

The return value will always be a model, even if the relation doesn't exist, but in that case the relation will be null when serializing the model.

The belongsTo relationship is used when a model is a member of another Target model.

It can be used in a one-to-one associations as the inverse of a hasOne. It can also used in one-to-many associations as the inverse of a hasMany (and is the one side of that association). In both cases, the belongsTo relationship is used for a model that is a member of another Target model, referenced by the foreignKey in the current model.

let Book = bookshelf.Model.extend({
  tableName: 'books',
  author: function() {
    return this.belongsTo(Author);
  }
});

// select * from `books` where id = 1
// select * from `authors` where id = book.author_id
Book.where({id: 1}).fetch({withRelated: ['author']}).then(function(book) {
  console.log(JSON.stringify(book.related('author')));
});

model.belongsToMany(Target, [table], [foreignKey], [otherKey], [foreignKeyTarget], [otherKeyTarget])Collection source

Parameters
  • Target Model

    Constructor of Model targeted by join.

  • [table] string

    Name of the joining table. Defaults to the two table names, joined by an underscore, ordered alphabetically.

  • [foreignKey] string

    Foreign key in this model. By default, the foreignKey is assumed to be the singular form of this model's tableName, followed by _id / _{{idAttribute}}.

  • [otherKey] string

    Foreign key in the Target model. By default, the otherKey is assumed to be the singular form of the Target model's tableName, followed by _id / _{{idAttribute}}.

  • [foreignKeyTarget] string

    Column in this model's table which foreignKey references, if other than id / idAttribute.

  • [otherKeyTarget] string

    Column in the Target model's table which otherKey references, if other than Target model's id / idAttribute.

Returns
Collection

Defines a many-to-many relation, where the current model is joined to one or more of a Target model through another table. The default name for the joining table is the two table names, joined by an underscore, ordered alphabetically. For example, a users table and an accounts table would have a joining table of accounts_users.

let Account = bookshelf.Model.extend({
  tableName: 'accounts'
});

let User = bookshelf.Model.extend({
  tableName: 'users',
  allAccounts: function () {
    return this.belongsToMany(Account);
  },
  adminAccounts: function() {
    return this.belongsToMany(Account).query({where: {access: 'admin'}});
  },
  viewAccounts: function() {
    return this.belongsToMany(Account).query({where: {access: 'readonly'}});
  }
});

The default key names in the joining table are the singular versions of the model table names, followed by _id / _{{idAttribute}}. So in the above case, the columns in the joining table would be user_id, account_id, and access, which is used as an example of how dynamic relations can be formed using different contexts. To customize the keys used in, or the tableName used for the join table, you may specify them like so:

 this.belongsToMany(Account, 'users_accounts', 'userid', 'accountid');

If you wish to create a belongsToMany association where the joining table has a primary key, and more information about the model, you may create a belongsToMany through relation:

let Doctor = bookshelf.Model.extend({
  patients: function() {
    return this.belongsToMany(Patient).through(Appointment);
  }
});

let Appointment = bookshelf.Model.extend({
  patient: function() {
    return this.belongsTo(Patient);
  },
  doctor: function() {
    return this.belongsTo(Doctor);
  }
});

let Patient = bookshelf.Model.extend({
  doctors: function() {
    return this.belongsToMany(Doctor).through(Appointment);
  }
});

Collections returned by a belongsToMany relation are decorated with several pivot helper methods. See attach, detach, updatePivot and withPivot for more information.

model.clear()Model source

Returns
Model

This model.

Clear all attributes on the model.

model.clone()Model source

Returns
Model

Cloned instance of this model.

Returns a new instance of the model with identical attributes, including any relations from the cloned model.

model.count([column], [options]) → Promise source

Example
Duck.where('color', 'blue').count('name')
  .then(function(count) { //...
Parameters
  • [column='*'] string

    Specify a column to count - rows with null values in this column will be excluded.

  • [options] Object

    Hash of options.

Since
  • 0.8.2
Returns
Promise

A promise resolving to the number of matching rows.

Gets the number of matching records in the database, respecting any previous calls to Model#query.

model.destroy([options]) → Promise<Model> source

Example
new User({id: 1})
  .destroy()
  .then(function(model) {
    // ...
  });
Parameters
  • [options] Object

    Hash of options.

    • [transacting] Transaction

      Optionally run the query in a transaction.

    • [require=true] Boolean

      Throw a Model.NoRowsDeletedError if no records are affected by destroy. This is the default behavior as of version 0.13.0.

Fires
Throws
Model.NoRowsDeletedError
Returns
Promise<Model>

A promise resolving to the destroyed and thus empty model, i.e. all attributes are undefined.

destroy performs a delete on the model, using the model's idAttribute to constrain the query.

A "destroying" event is triggered on the model before being destroyed. To prevent destroying the model, throwing an error inside one of the event listeners will stop destroying the model and reject the promise.

A "destroyed" event is fired after the model's removal is completed.

model.escape(attribute) → string source

Parameters
  • attribute string

    The attribute to escape.

Returns
string

HTML-escaped value of an attribute.

Get the HTML-escaped value of an attribute.

model.fetch([options]) → Promise<Model|null> source

Parameters
  • [options] Object

    Hash of options.

    • [require=false] Boolean

      Reject the returned response with a NotFoundError if results are empty.

    • [columns='*'] string|string[]

      Specify columns to be retrieved.

    • [transacting] Transaction

      Optionally run the query in a transaction.

    • [lock] string

      Type of row-level lock to use. Valid options are forShare and forUpdate. This only works in conjunction with the transacting option, and requires a database that supports it.

    • [withRelated] string|Object|mixed[]

      Relations to be retrieved with Model instance. Either one or more relation names or objects mapping relation names to query callbacks.

Fires
Throws
Model.NotFoundError
Returns
Promise<Model|null>

A promise resolving to the fetched model or null if none exists.

Fetches a model from the database, using any attributes currently set on the model to form a select query.

A "fetching" event will be fired just before the record is fetched; a good place to hook into for validation. "fetched" event will be fired when a record is successfully retrieved.

If you need to constrain the query performed by fetch, you can call query before calling fetch.

// select * from `books` where `ISBN-13` = '9780440180296'
new Book({'ISBN-13': '9780440180296'})
  .fetch()
  .then(function(model) {
    // outputs 'Slaughterhouse Five'
    console.log(model.get('title'));
  });

If you'd like to only fetch specific columns, you may specify a columns property in the options for the fetch call, or use query, tapping into the Knex column method to specify which columns will be fetched.

A single property, or an array of properties can be specified as a value for the withRelated property. You can also execute callbacks on relations queries (eg. for sorting a relation). The results of these relation queries will be loaded into a relations property on the model, may be retrieved with the related method, and will be serialized as properties on a toJSON call unless {shallow: true} is passed.

let Book = bookshelf.Model.extend({
  tableName: 'books',
  editions: function() {
    return this.hasMany(Edition);
  },
  chapters: function() {
    return this.hasMany(Chapter);
  },
  genre: function() {
    return this.belongsTo(Genre);
  }
})

new Book({'ISBN-13': '9780440180296'}).fetch({
  withRelated: [
    'genre', 'editions',
    { chapters: function(query) { query.orderBy('chapter_number'); }}
  ]
}).then(function(book) {
  console.log(book.related('genre').toJSON());
  console.log(book.related('editions').toJSON());
  console.log(book.toJSON());
});

model.fetchAll([options]) → Promise<Collection> source

Parameters
  • [options] Object

    Hash of options.

    • [require=false] Boolean

      Rejects the returned promise with an Collection.EmptyError if no records are returned.

    • [transacting] Transaction

      Optionally run the query in a transaction.

Fires
Throws
Collection.EmptyError

Rejects the promise in the event of an empty response if the require: true option.

Returns
Promise<Collection>

A promise resolving to the fetched collection.

Fetches a collection of models from the database, using any query parameters currently set on the model to form a select query. Returns a promise, which will resolve with the fetched collection. If you wish to trigger an error if no models are found, pass {require: true} as one of the options to the fetchAll call.

If you need to constrain the query performed by fetch, you can call the query method before calling fetch.

model.fetchPage(options) → Promise<Model|null> source

Example
Car
.query(function (qb) {
   qb.innerJoin('manufacturers', 'cars.manufacturer_id', 'manufacturers.id');
   qb.groupBy('cars.id');
   qb.where('manufacturers.country', '=', 'Sweden');
})
.orderBy('-productionYear') // Same as .orderBy('cars.productionYear', 'DESC')
.fetchPage({
   pageSize: 15, // Defaults to 10 if not specified
   page: 3, // Defaults to 1 if not specified

   // OR
   // limit: 15,
   // offset: 30,

   withRelated: ['engine'] // Passed to Model#fetchAll
})
.then(function (results) {
   console.log(results); // Paginated results object with metadata example below
})

// Pagination results:

{
   models: [<Car>], // Regular bookshelf Collection
   // other standard Collection attributes
   ...
   pagination: {
       rowCount: 53, // Total number of rows found for the query before pagination
       pageCount: 4, // Total number of pages of results
       page: 3, // The requested page number
       pageSize: 15, // The requested number of rows per page

 // OR, if limit/offset pagination is used instead of page/pageSize:
       // offset: 30, // The requested offset
       // limit: 15 // The requested limit
   }
}
Parameters
  • options object

    The pagination options, plus any additional options that will be passed to Model#fetchAll

Returns
Promise<Model|null>

In order to use this function, you must have the Pagination plugin installed.

model.format(attributes) → Object source

Parameters
  • attributes Object

    The attributes to be converted.

Returns
Object

Formatted attributes.

The format method is used to modify the current state of the model before it is persisted to the database. The attributes passed are a shallow clone of the model, and are only used for inserting/updating - the current values of the model are left intact.

Do note that format is used to modify the state of the model when accessing the database, so if you remove an attribute in your format method, that attribute will never be persisted to the database, but it will also never be used when doing a fetch(), which may cause unexpected results. You should be very cautious with implementations of this method that may remove the primary key from the list of attributes.

If you need to modify the database data before it is given to the model, override the parse method instead. That method does the opposite operation of format.

model.get(attribute) → mixed source

Example
note.get("title");
Parameters
  • attribute string

    The name of the attribute to retrieve.

Returns
mixed

Attribute value.

Get the current value of an attribute from the model.

model.has(attribute) → Boolean source

Parameters
  • attribute string

    The attribute to check.

Returns
Boolean

True if attribute is set, otherwise false.

Returns true if the attribute contains a value that is not null or undefined.

model.hasChanged([attribute]) → Boolean source

Example
Author.forge({id: 1}).fetch().then(function(author) {
  author.hasChanged() // false
  author.set('name', 'Bob')
  author.hasChanged('name') // true
})
Parameters
  • [attribute] string

    A specific attribute to check for changes.

Returns
Boolean

true if any attribute has changed, false otherwise. Alternatively, if the attribute argument was specified, checks if that particular attribute has changed.

Returns true if any attribute has changed since the last fetch or save. If an attribute name is passed as argument, returns true only if that specific attribute has changed.

Note that even if an attribute is changed by using the set method, but the new value is exactly the same as the existing one, the attribute is not considered changed.

model.hasMany(Target, [foreignKey], [foreignKeyTarget])Collection source

Parameters
  • Target Model

    Constructor of Model targeted by join.

  • [foreignKey] string

    ForeignKey in the Target model. By default, the foreignKey is assumed to be the singular form of this model's tableName, followed by _id / _{{idAttribute}}.

  • [foreignKeyTarget] string

    Column in this model's table which foreignKey references, if other than this model's id / idAttribute.

Returns
Collection

The hasMany relation specifies that this model has one or more rows in another table which match on this model's primary key.

let Author = bookshelf.Model.extend({
  tableName: 'authors',
  books: function() {
    return this.hasMany(Book);
  }
});

// select * from `authors` where id = 1
// select * from `books` where author_id = 1
Author.where({id: 1}).fetch({withRelated: ['books']}).then(function(author) {
  console.log(JSON.stringify(author.related('books')));
});

model.hasOne(Target, [foreignKey], [foreignKeyTarget])Model source

Parameters
  • Target Model

    Constructor of Model targeted by join.

  • [foreignKey] string

    ForeignKey in the Target model. By default, the foreignKey is assumed to be the singular form of this model's tableName, followed by _id / _{{idAttribute}}.

  • [foreignKeyTarget] string

    Column in this model's table which foreignKey references, if other than this model's id / idAttribute.

Returns
Model

The return value will always be a model, even if the relation doesn't exist, but in that case the relation will be null when serializing the model.

The hasOne relation specifies that this table has exactly one of another type of object, specified by a foreign key in the other table.

let Record = bookshelf.Model.extend({
  tableName: 'health_records'
});

let Patient = bookshelf.Model.extend({
  tableName: 'patients',
  record: function() {
    return this.hasOne(Record);
  }
});

// select * from `health_records` where `patient_id` = 1;
new Patient({id: 1}).related('record').fetch().then(function(model) {
  // ...
});

// alternatively, if you don't need the relation loaded on the patient's relations hash:
new Patient({id: 1}).record().fetch().then(function(model) {
  // ...
});

model.isNew() source

Example
var modelA = new bookshelf.Model();
modelA.isNew(); // true

var modelB = new bookshelf.Model({id: 1});
modelB.isNew(); // false

Checks for the existence of an id to determine whether the model is considered "new".

model.load(relations, [options]) → Promise<Model> source

Example
new Posts().fetch().then(function(collection) {
  collection.at(0)
  .load(['author', 'content', 'comments.tags'])
  .then(function(model) {
    JSON.stringify(model);
  });
});

{
  title: 'post title',
  author: {...},
  content: {...},
  comments: [
    {tags: [...]}, {tags: [...]}
  ]
}
Parameters
  • relations string|Object|mixed[]

    The relation, or relations, to be loaded.

  • [options] Object

    Hash of options.

    • [transacting] Transaction

      Optionally run the query in a transaction.

    • [lock] string

      Type of row-level lock to use. Valid options are forShare and forUpdate. This only works in conjunction with the transacting option, and requires a database that supports it.

Returns
Promise<Model>

A promise resolving to this model.

The load method takes an array of relations to eager load attributes onto a Model, in a similar way that the withRelated property works on fetch. Dot separated attributes may be used to specify deep eager loading.

model.morphMany(Target, [name], [columnNames], [morphValue])Collection source

Parameters
  • Target Model

    Constructor of Model targeted by join.

  • [name] string

    Prefix for _id and _type columns.

  • [columnNames] string[]

    Array containing two column names, the first is the _type, the second is the _id.

  • [morphValue=Target#tablename] string

    The string value associated with this relationship. Stored in the _type column of the polymorphic table. Defaults to Target# tablename.

Returns
Collection

A collection of related models.

morphMany is essentially the same as a morphOne, but creating a collection rather than a model (similar to a hasOne vs. hasMany relation).

morphMany is used to signify a one-to-many or many-to-many polymorphic relation with another Target model, where the name of the model is used to determine which database table keys are used. The naming convention requires the name prefix an _id and _type field in the database. So for the case below the table names would be imageable_type and imageable_id. The morphValue may be optionally set to store/retrieve a different value in the _type column than the Target's tableName.

let Post = bookshelf.Model.extend({
  tableName: 'posts',
  photos: function() {
    return this.morphMany(Photo, 'imageable');
  }
});

And with custom columnNames:

let Post = bookshelf.Model.extend({
  tableName: 'posts',
  photos: function() {
    return this.morphMany(Photo, 'imageable', ["ImageableType", "ImageableId"]);
  }
});

model.morphOne(Target, [name], [columnNames], [morphValue])Model source

Parameters
  • Target Model

    Constructor of Model targeted by join.

  • [name] string

    Prefix for _id and _type columns.

  • [columnNames] string[]

    Array containing two column names, the first is the _type, the second is the _id.

  • [morphValue=Target#tableName] string

    The string value associated with this relationship. Stored in the _type column of the polymorphic table. Defaults to Target#tableName.

Returns
Model

The related model.

The morphOne is used to signify a one-to-one polymorphic relation with another Target model, where the name of the model is used to determine which database table keys are used. The naming convention requires the name prefix an _id and _type field in the database. So for the case below the table names would be imageable_type and imageable_id. The morphValue may be optionally set to store/retrieve a different value in the _type column than the Model#tableName.

let Site = bookshelf.Model.extend({
  tableName: 'sites',
  photo: function() {
    return this.morphOne(Photo, 'imageable');
  }
});

And with custom columnNames:

let Site = bookshelf.Model.extend({
  tableName: 'sites',
  photo: function() {
    return this.morphOne(Photo, 'imageable', ["ImageableType", "ImageableId"]);
  }
});

Note that both columnNames and morphValue are optional arguments. How your argument is treated when only one is specified, depends on the type. If your argument is an array, it will be assumed to contain custom columnNames. If it's not, it will be assumed to indicate a morphValue.

model.morphTo(name, [columnNames], Target)Model source

Parameters
  • name string

    Prefix for _id and _type columns.

  • [columnNames] string[]

    Array containing two column names, the first is the _type, the second is the _id.

  • Target Model

    Constructor of Model targeted by join.

Returns
Model

The morphTo relation is used to specify the inverse of the morphOne or morphMany relations, where the targets must be passed to signify which models are the potential opposite end of the polymorphic relation.

let Photo = bookshelf.Model.extend({
  tableName: 'photos',
  imageable: function() {
    return this.morphTo('imageable', Site, Post);
  }
});

And with custom columnNames:

let Photo = bookshelf.Model.extend({
  tableName: 'photos',
  imageable: function() {
    return this.morphTo('imageable', ["ImageableType", "ImageableId"], Site, Post);
  }
});

And with custom morphValues, the inverse of morphValue of morphOne and morphMany, where the morphValues may be optionally set to check against a different value in the _type column than the Model#tableName; for example, a more descriptive name, or a name that betters adheres to whatever standard you are using for models.

let Photo = bookshelf.Model.extend({
  tableName: 'photos',
  imageable: function() {
    return this.morphTo('imageable', [Site, "favicon"], [Post, "cover_photo"]);
  }
});

model.off() source

Example
customer.off('fetched fetching');
ship.off(); // This will remove all event listeners
See

model.on() source

Example
customer.on('fetching', function(model, columns) {
  // Do something before the data is fetched from the database
});
See

model.once(nameOrNames, callback) source

Parameters
  • nameOrNames string

    The name of the event or space separated list of events to register a callback for.

  • callback function

    That callback to invoke only once when the event is fired.

Just like Events#on, but causes the bound callback to fire only once before being removed. Handy for saying "the next time that X happens, do this". When multiple events are passed in using the space separated syntax, the event will fire once for every event you passed in, not once for a combination of all events.

model.orderBy(sort, order) source

Example
Car.forge().orderBy('color', 'ASC').fetchAll()
   .then(function (rows) { // ...
Parameters
  • sort string

    Column to sort on

  • order string

    Ascending ('ASC') or descending ('DESC') order

Since
  • 0.9.3

Specifies the column to sort on and sort order.

The order parameter is optional, and defaults to 'ASC'. You may also specify 'DESC' order by prepending a hyphen to the sort column name. orderBy("date", 'DESC') is the same as orderBy("-date").

Unless specified using dot notation (i.e., "table.column"), the default table will be the table name of the model orderBy was called on.

model.parse(attributes) → Object source

Example
// Example of a parser to convert snake_case to camelCase, using lodash
// This is just an example. You can use the built-in case-converter plugin
// to achieve the same functionality.
model.parse = function(attrs) {
  return _.mapKeys(attrs, function(value, key) {
    return _.camelCase(key);
  });
};
Parameters
  • attributes Object

    Hash of attributes to parse.

Returns
Object

Parsed attributes.

The parse method is called whenever a model's data is returned in a fetch call. The function is passed the raw database response object, and should return the attributes hash to be set on the model. The default implementation is a no-op, simply passing through the JSON response. Override this if you need to format the database responses - for example calling JSON.parse on a text field containing JSON, or explicitly typecasting a boolean in a sqlite3 database response.

If you need to format your data before it is saved to the database, override the format method in your models. That method does the opposite operation of parse.

model.previous(attribute) → mixed source

Example
Author.forge({id: 1}).fetch().then(function(author) {
  author.get('name') // Alice
  author.set('name', 'Bob')
  author.previous('name') // 'Alice'
})
Parameters
  • attribute string

    The attribute to check.

Returns
mixed

The previous value.

Returns the value of an attribute like it was before the last change. A change is usually done with the set method, but it can also be done with the save method. This is useful for getting back the original attribute value after it's been changed. It can also be used to get the original value after a model has been saved to the database or destroyed.

In case you want to get the previous value of all attributes at once you should use the previousAttributes method.

Note that this will return undefined if the model hasn't been fetched, saved, destroyed or eager loaded. However, in case one of these operations did take place, it will return the current value if an attribute hasn't changed. If you want to check if an attribute has changed see the hasChanged method.

model.previousAttributes() → Object source

Example
Author.forge({id: 1}).fetch().then(function(author) {
  author.get('name') // Alice
  author.set('name', 'Bob')
  author.previousAttributes() // {id: 1, name: 'Alice'}
})

Author.forge({id: 1}).fetch().then(function(author) {
  author.get('name') // Alice
  return author.save({name: 'Bob'})
}).then(function(author) {
  author.get('name') // Bob
  author.previousAttributes() // {id: 1, name: 'Alice'}
})
Returns
Object

The attributes as they were before the last change, or an empty object in case the model data hasn't been fetched yet.

Returns a copy of the model's attributes like they were before the last change. A change is usually done with the set method, but it can also be done with the save method. This is mostly useful for getting a diff of the model's attributes after changing some of them. It can also be used to get the previous state of a model after it has been saved to the database or destroyed.

In case you want to get the previous value of a single attribute you should use the previous method.

Note that this will return an empty object if no changes have been made to the model and it hasn't been fetched, saved or eager loaded.

model.query(arguments)Model|QueryBuilder source

Example
model
  .query('where', 'other_id', '=', '5')
  .fetch()
  .then(function(model) {
    // ...
  });

model
  .query({where: {other_id: '5'}, orWhere: {key: 'value'}})
  .fetch()
  .then(function(model) {
    // ...
  });

model.query(function(qb) {
  qb.where('other_person', 'LIKE', '%Demo').orWhere('other_id', '>', 10);
}).fetch()
  .then(function(model) {
    // ...
  });

let qb = model.query();
qb.where({id: 1}).select().then(function(resp) {
  // ...
});
Parameters
  • arguments function|Object|string

    The query method.

See
Returns
Model|QueryBuilder

Will return this model or, if called with no arguments, the underlying query builder.

The query method is used to tap into the underlying Knex query builder instance for the current model. If called with no arguments, it will return the query builder directly. Otherwise, it will call the specified method on the query builder, applying any additional arguments from the model.query call. If the method argument is a function, it will be called with the Knex query builder as the context and the first argument, returning the current model.

model.refresh(options) → Promise<Model> source

Parameters
  • options Object

    A hash of options. See Model#fetch for details.

Since
  • 0.8.2
Returns
Promise<Model>

A promise resolving to this model.

Update the attributes of a model, fetching it by its primary key. If no attribute matches its idAttribute, then fetch by all available fields.

Example
new Photo({id: 1}).fetch({
  withRelated: ['account']
}).then(function(photo) {
  if (photo) {
    var account = photo.related('account');
    if (account.id) {
       return account.related('trips').fetch();
    }
  }
});
Parameters
  • name string

    The name of the relation to retrieve.

Returns
Model|Collection|undefined

The specified relation as defined by a method on the model, or undefined if it does not exist.

The related method returns a specified relation loaded on the relations hash on the model, or calls the associated relation method and adds it to the relations hash if one exists and has not yet been loaded.

model.resetQuery()Model source

Returns
Model

Self, this method is chainable.

Used to reset the internal state of the current query builder instance. This method is called internally each time a database action is completed by Sync

model.save([key], [val], [attrs], [options]) → Promise<Model> source

Example
// Save with no arguments
Model.forge({id: 5, firstName: 'John', lastName: 'Smith'}).save().then(function() {
  //...
});

// Or add attributes during save
Model.forge({id: 5}).save({firstName: 'John', lastName: 'Smith'}).then(function() {
  //...
});

// Or, if you prefer, for a single attribute
Model.forge({id: 5}).save('name', 'John Smith').then(function() {
  //...
});
Parameters
  • [key] string

    Attribute name.

  • [val] string

    Attribute value.

  • [attrs] Object

    A hash of attributes.

  • [options] Object
    • [transacting] Transaction

      Optionally run the query in a transaction.

    • [method] string

      Explicitly select a save method, either "update" or "insert".

    • [defaults=false] Boolean

      Whether to assign or not default attribute values on a model when performing an update or create operation.

    • [patch=false] Boolean

      Only save attributes supplied in arguments to save.

    • [require=true] Boolean

      Throw a Model.NoRowsUpdatedError if no records are affected by save.

Fires
Throws
Model.NoRowsUpdatedError
Returns
Promise<Model>

A promise resolving to the saved and updated model.

This method is used to perform either an insert or update query using the model's set attributes.

If the model isNew, any defaults will be set and an insert query will be performed. Otherwise it will update the record with a corresponding ID. It is also possible to set default attributes on an update by passing the {defaults: true} option in the second argument to the save call. This will also use the same defaults as the insert operation.

The type of operation to perform (either insert or update) can be overriden with the method option:

// This forces an insert with the specified id instead of the expected
// update
new Post({name: 'New Article', id: 34})
  .save(null, {method: 'insert'})
  .then(function(model) {
    // ...
  });

If you only wish to update with the params passed to the save, you may pass a {patch: true} option in the second argument to save:

// UPDATE authors SET "bio" = 'Short user bio' WHERE "id" = 1
new Author({id: 1, first_name: 'User'})
  .save({bio: 'Short user bio'}, {patch: true})
  .then(function(model) {
    // ...
  });

Several events fire on the model when saving: a "creating", or "updating" event if the model is being inserted or updated, and a "saving" event in either case.

To prevent saving the model (for example, with validation), throwing an error inside one of these event listeners will stop saving the model and reject the promise.

A "created", or "updated" event is fired after the model is saved, as well as a "saved" event either way. If you wish to modify the query when the "saving" event is fired, the knex query object is available in options.query.

See the Events guide for further details.

model.serialize([options]) → Object source

Example
var artist = new bookshelf.Model({
  firstName: "Wassily",
  lastName: "Kandinsky"
});

artist.set({birthday: "December 16, 1866"});

console.log(JSON.stringify(artist));
// {firstName: "Wassily", lastName: "Kandinsky", birthday: "December 16, 1866"}
Parameters
  • [options] Object
    • [shallow=false] Boolean

      Exclude relations.

    • [omitPivot=false] Boolean

      Exclude pivot values.

Returns
Object

Serialized model as a plain object.

Return a copy of the model's attributes for JSON stringification. If the model has any relations defined, this will also call toJSON on each of the related objects, and include them on the object unless {shallow: true} is passed as an option.

serialize is called internally by toJSON. Override this function if you want to customize its output.

model.set(attribute, [value], [options])Model source

Example
customer.set({first_name: "Joe", last_name: "Customer"});
customer.set("telephone", "555-555-1212");
Parameters
  • attribute string|Object

    Attribute name, or hash of attribute names and values.

  • [value] mixed

    If a string was provided for attribute, the value to be set.

  • [options] Object
    • [unset=false] Object

      Remove attributes from the model instead of setting them.

Returns
Model

This model.

Set a hash of attributes (one or many) on the model.

model.through(Interim, [throughForeignKey], [otherKey], [throughForeignKeyTarget], [otherKeyTarget])Collection source

Parameters
  • Interim Model

    Pivot model.

  • [throughForeignKey] string

    Foreign key in this model. By default, the foreignKey is assumed to be the singular form of the Target model's tableName, followed by _id / _{{idAttribute}}.

  • [otherKey] string

    Foreign key in the Interim model. By default, the otherKey is assumed to be the singular form of this model's tableName, followed by _id / _{{idAttribute}}.

  • [throughForeignKeyTarget] string

    Column in the Target model which throughForeignKey references, if other than Target model's id / idAttribute.

  • [otherKeyTarget] string

    Column in this model which otherKey references, if other than id / idAttribute.

Returns
Collection

Helps to create dynamic relations between models and collections, where a hasOne, hasMany, belongsTo, or belongsToMany relation may run through a JoinModel.

A good example of where this would be useful is if a book hasMany paragraphs through chapters. Consider the following examples:

let Book = bookshelf.Model.extend({
  tableName: 'books',

  // Find all paragraphs associated with this book, by
  // passing through the "Chapter" model.
  paragraphs: function() {
    return this.hasMany(Paragraph).through(Chapter);
  },

  chapters: function() {
    return this.hasMany(Chapter);
  }
});

let Chapter = bookshelf.Model.extend({
  tableName: 'chapters',

  paragraphs: function() {
    return this.hasMany(Paragraph);
  }
});

let Paragraph = bookshelf.Model.extend({
  tableName: 'paragraphs',

  chapter: function() {
    return this.belongsTo(Chapter);
  },

  // A reverse relation, where we can get the book from the chapter.
  book: function() {
    return this.belongsTo(Book).through(Chapter);
  }
});

The "through" table creates a pivot model, which it assigns to model.pivot after it is created. On toJSON, the pivot model is flattened to values prefixed with _pivot_.

model.timestamp([options]) → Object source

Parameters
  • [options] Object
    • [method] string

      Either 'insert' or 'update' to specify what kind of save the attribute update is for.

    • [date] string

      Either a Date object or ms since the epoch. Specify what date is used for updateing the timestamps, i.e. if something other than new Date() should be used.

Returns
Object

A hash of timestamp attributes that were set.

Automatically sets the timestamp attributes on the model, if hasTimestamps is set to true or an array. It checks if the model is new and sets the created_at and updated_at attributes (or any other custom attribute names you have set) to the current date. If the model is not new and is just being updated then only the updated_at attribute gets automatically updated.

If the model contains any user defined created_at or updated_at values, there won't be any automatic updated of these attributes and the user supplied values will be used instead.

model.toJSON([options]) source

Parameters

Called automatically by JSON.stringify. To customize serialization, override serialize.

model.trigger() source

Example
ship.trigger('fetched');
See

model.triggerThen(name, [args]) source

Parameters
  • name string

    The event name, or a whitespace-separated list of event names, to be triggered.

  • [args] mixed

    Arguments to be passed to any registered event handlers.

Returns

Promise A promise resolving the the resolved return values of any triggered handlers.

A promise version of Events#trigger, returning a promise which resolves with all return values from triggered event handlers. If any of the event handlers throw an Error or return a rejected promise, the promise will be rejected. Used internally on the "creating", "updating", "saving", and "destroying" events, and can be helpful when needing async event handlers (e.g. for validations).

model.unset(attribute)Model source

Parameters
  • attribute

    Attribute to unset.

Returns
Model

This model.

Remove an attribute from the model. unset is a noop if the attribute doesn't exist.

Note that unsetting an attribute from the model will not affect the related record's column value when saving the model. In order to clear the value of a column in the database record, set the attribute value to null instead: model.set("column_name", null).

model.where(method)Model source

Example
model.where('favorite_color', '<>', 'green').fetch().then(function() { //...
// or
model.where('favorite_color', 'red').fetch().then(function() { //...
// or
model.where({favorite_color: 'red', shoe_size: 12}).fetch().then(function() { //...
Parameters
  • method Object|string

    Either key, [operator], value syntax, or a hash of attributes to match. Note that these must be formatted as they are in the database, not how they are stored after Model#parse.

See
Returns
Model

Self, this method is chainable.

The where method is used as convenience for the most common query method, adding a where clause to the builder. Any additional knex methods may be accessed using query.

Accepts either key, value syntax, or a hash of attributes.

Lodash Methods

Events

model.on("counting", (model, options) => source

Parameters
  • model Model

    The model firing the event.

  • options Object

    Options object passed to count.

Tutorials
Returns
Promise

Counting event.

Fired before a count query. A promise may be returned from the event handler for async behaviour.

model.on("created", (model, newId, options) => source

Parameters
  • model Model

    The model firing the event.

  • newId Array

    A list containing the id of the newly created model.

  • options Object

    Options object passed to save.

Tutorials
Returns
Promise

Created event.

Fired after an insert query.

model.on("creating", (model, attrs, options) => source

Parameters
  • model Model

    The model firing the event.

  • attrs Object

    Attributes that will be inserted.

    Note: There's currently a bug that leads to attrs only containing attributes that were passed as argument to save. You can work around this by accessing model.changed which does contain all the attributes that will be inserted.

  • options Object

    Options object passed to save.

Tutorials
Returns
Promise

Creating event.

Fired before insert query. A promise may be returned from the event handler for async behaviour. Throwing an exception from the handler will cancel the save operation.

model.on("destroyed", (model, options) => source

Parameters
  • model Model

    The model firing the event.

  • options Object

    Options object passed to destroy.

Tutorials
Returns
Promise

Destroyed event.

Fired after a delete query. A promise may be returned from the event handler for async behaviour.

model.on("destroying", (model, options) => source

Parameters
  • model Model

    The model firing the event.

  • options Object

    Options object passed to destroy.

Tutorials
Returns
Promise

Destroying event.

Fired before a delete query. A promise may be returned from the event handler for async behaviour. Throwing an exception from the handler will reject the promise and cancel the deletion.

model.on("fetched", (model, response, options) => source

Parameters
  • model Model

    The model firing the event.

  • response Object

    Knex query response.

  • options Object

    Options object passed to fetch.

Tutorials
Returns
Promise

If the handler returns a promise, fetch will wait for it to be resolved.

Fired after a fetch operation. A promise may be returned from the event handler for async behaviour.

model.on("fetching", (model, columns, options) => source

Parameters
  • model Model

    The model which is about to be fetched.

  • columns string[]

    The columns to be retrieved by the query.

  • options Object

    Options object passed to fetch.

    • query QueryBuilder

      Query builder to be used for fetching. This can be modified to change the query before it is executed.

Tutorials
Returns
Promise

Fired before a fetch operation. A promise may be returned from the event handler for async behaviour.

model.on("saved", (model, response, options) => source

Parameters
  • model Model

    The model firing the event.

  • response Array|Number

    A list containing the id of the newly created model in case of an insert or a number representing the affected rows in the case of an update query.

  • options Object

    Options object passed to save.

Tutorials
Returns
Promise

Saved event.

Fired after an insert or update query.

model.on("saving", (model, attrs, options) => source

Parameters
  • model Model

    The model firing the event. Its attributes are already changed but not commited to the database yet.

  • attrs Object

    Attributes that will be inserted or updated.

    Note: There's currently a bug that leads to attrs only containing attributes that were passed as argument to save. You can work around this by accessing model.changed which does contain all the attributes that will be inserted or updated.

  • options Object

    Options object passed to save.

Tutorials
Returns
Promise

Saving event.

Fired before an insert or update query. A promise may be returned from the event handler for async behaviour. Throwing an exception from the handler will cancel the save.

model.on("updated", (model, affectedRows, options) => source

Parameters
  • model Model

    The model firing the event.

  • affectedRows Number

    Number of rows affected by the update.

  • options Object

    Options object passed to save.

Tutorials
Returns
Promise

Updated event.

Fired after an update query.

model.on("updating", (model, attrs, options) => source

Parameters
  • model Model

    The model firing the event. Its attributes are already changed but not commited to the database yet.

  • attrs Object

    Attributes that will be updated.

    Note: There's currently a bug that leads to attrs only containing attributes that were passed as argument to save. You can work around this by accessing model.changed which does contain all the attributes that will be updated.

  • options Object

    Options object passed to save.

Tutorials
Returns
Promise

Updating event.

Fired before update query. A promise may be returned from the event handler for async behaviour. Throwing an exception from the handler will cancel the save operation.

model.on("fetched:collection", (collection, response, options) => source

Parameters
  • collection Collection

    The collection that has been fetched.

  • response Object

    The raw response from the underlying query builder. This will be an array with objects representing each row, similar to the output of a serialized Model.

  • options Object

    Options object passed to fetchAll.

Tutorials
Returns
Promise

Fired after a fetchAll operation. A promise may be returned from the event handler for async behaviour.

model.on("fetching:collection", (collection, columns, options) => source

Parameters
  • collection Collection

    The collection that is going to be fetched. At this point it's still empty since the fetch hasn't happened yet.

  • columns string[]

    The columns to be retrieved by the query as provided by the underlying query builder. If the columns option is not specified the value of this will usually be an array with a single string 'tableName.*'.

  • options Object

    Options object passed to fetchAll.

Tutorials
Returns
Promise

Fired before a fetchAll operation. A promise may be returned from the event handler for async behaviour.

Model.NoRowsUpdatedError

Construction

new Model.NoRowsUpdatedError() source

Thrown when no records are saved by save unless called with the {require: false} option.

Collection

Collections are ordered sets of models returned from the database, from a fetchAll call. They may be used with a suite of Lodash methods.

Construction

new Collection([models], [options]) source

Example
let tabs = new TabSet([tab1, tab2, tab3]);
Parameters
  • [models] Model[]

    Initial array of models.

  • [options] Object
    • [comparator=false] Boolean

      Comparator for collection, or false to disable sorting.

When creating a Collection, you may choose to pass in the initial array of models. The collection's comparator may be included as an option. Passing false as the comparator option will prevent sorting. If you define an initialize function, it will be invoked when the collection is created.

collection.initialize() source

Called by the Collection constructor when creating a new instance. Override this function to add custom initialization, such as event listeners. Because plugins may override this method in subclasses, make sure to call your super (extended) class. e.g.

initialize: function() {
  this.constructor.__super__.initialize.apply(this, arguments);
  // Your initialization code ...
}

Static

Collection.extend([prototypeProperties], [classProperties]) → function source

Parameters
  • [prototypeProperties] Object

    Instance methods and properties to be attached to instances of the new class.

  • [classProperties] Object

    Class (ie. static) functions and properties to be attached to the constructor of the new class.

Returns
function

Constructor for new Collection subclass.

To create a Collection class of your own, extend Bookshelf.Collection.

Collection.forge([models], options) source

Example
var Promise = require('bluebird');
var Accounts = bookshelf.Collection.extend({
  model: Account
});

var accounts = Accounts.forge([
  {name: 'Person1'},
  {name: 'Person2'}
]);

Promise.all(accounts.invokeMap('save')).then(function() {
  // collection models should now be saved...
});
Parameters
  • [models] Object[]|Model[]

    Set of models (or attribute hashes) with which to initialize the collection.

  • options Object

    Hash of options.

A simple helper function to instantiate a new Collection without needing new.

Members

collection.length :Number source

Example
var vanHalen = new bookshelf.Collection([eddie, alex, stone, roth]);
console.log(vanHalen.length) // 4

This is the total number of models in the collection. Note that this may not represent how many models there are in total in the database.

Methods

collection.add(models, [options])Collection source

Example
const ships = new bookshelf.Collection;

ships.add([
  {name: "Flying Dutchman"},
  {name: "Black Pearl"}
]);
Parameters
  • models Object[]|Model[]|Object|Model

    One or more models or raw attribute objects.

  • [options] Object

    Options for controlling how models are added.

    • [merge=false] Boolean

      If set to true it will merge the attributes of duplicate models with the attributes of existing models in the collection.

    • [at] Number

      If set to a number equal to or greater than 0 it will splice the model into the collection at the specified index number.

Returns
Collection

Self, this method is chainable.

Add a model, or an array of models, to the collection. You may also pass raw attribute objects, which will be converted to proper models when being added to the collection.

You can pass the {at: index} option to splice the model into the collection at the specified index.

By default if you're adding models to the collection that are already present, they'll be ignored, unless you pass {merge: true}, in which case their attributes will be merged with the corresponding models.

collection.at() source

Get a model from a collection, specified by index. Useful if your collection is sorted, and if your collection isn't sorted, at will still retrieve models in insertion order.

collection.attach(ids, options) → Promise<Collection> source

Parameters
  • ids mixed|mixed[]

    One or more ID values or models to be attached to the relation.

  • options Object

    A hash of options.

    • transacting Transaction

      Optionally run the query in a transaction.

Returns
Promise<Collection>

A promise resolving to the updated Collection where this method was called.

Attaches one or more ids or models from a foreign table to the current table, on a many-to-many relation. Creates and saves a new model and attaches the model with the related model.

var admin1 = new Admin({username: 'user1', password: 'test'});
var admin2 = new Admin({username: 'user2', password: 'test'});

Promise.all([admin1.save(), admin2.save()])
  .then(function() {
    return Promise.all([
    new Site({id: 1}).admins().attach([admin1, admin2]),
    new Site({id: 2}).admins().attach(admin2)
  ]);
})

This method (along with Collection#detach and Collection#updatePivot) are mixed in to a Collection when returned by a belongsToMany relation.

collection.clone() source

Create a new collection with an identical list of models as this one.

collection.count([column], [options]) → Promise source

Example
// select count(*) from shareholders where company_id = 1 and share &gt; 0.1;
Company.forge({id:1})
  .shareholders()
  .query('where', 'share', '>', '0.1')
  .count()
  .then(function(count) {
    assert(count === 3);
  });
Parameters
  • [column='*'] string

    Specify a column to count - rows with null values in this column will be excluded.

  • [options] Object

    Hash of options.

Since
  • 0.8.2
Returns
Promise

A promise resolving to the number of matching rows.

Get the number of records in the collection's table.

collection.create(model, [options]) → Promise<Model> source

Parameters
  • model Object

    A set of attributes to be set on the new model.

  • [options] Object
    • [transacting] Transaction
Returns
Promise<Model>

A promise resolving with the new model.

Convenience method to create a new model instance within a collection. Equivalent to instantiating a model with a hash of attributes, saving the model to the database then adding the model to the collection.

When used on a relation, create will automatically set foreign key attributes before persisting the Model.

const { courses, ...attributes } = req.body;

Student.forge(attributes).save().tap(student =>
  Promise.map(courses, course => student.related('courses').create(course))
).then(student =>
  res.status(200).send(student)
).catch(error =>
  res.status(500).send(error.message)
);

collection.detach([ids], options) → Promise source

Parameters
  • [ids] mixed|mixed[]

    One or more ID values or models to be detached from the relation.

  • options Object

    A hash of options.

    • transacting Transaction

      Optionally run the query in a transaction.

Returns
Promise

A promise resolving to the updated Collection where this method was called.

Detach one or more related objects from their pivot tables. If a model or id is passed, it attempts to remove from the pivot table based on that foreign key. If no parameters are specified, we assume we will detach all related associations.

This method (along with Collection#attach and Collection#updatePivot) are mixed in to a Collection when returned by a belongsToMany relation.

collection.fetch([options]) → Promise<Collection> source

Parameters
  • [options] Object
    • [require=false] Boolean

      Trigger a Collection.EmptyError if no records are found.

    • [withRelated=[]] string|string[]

      A relation, or list of relations, to be eager loaded as part of the fetch operation.

Fires
Throws
Collection.EmptyError

Upon a sucessful query resulting in no records returns. Only fired if require: true is passed as an option.

Returns
Promise<Collection>

Fetch the default set of models for this collection from the database, resetting the collection when they arrive. If you wish to trigger an error if the fetched collection is empty, pass {require: true} as one of the options to the fetch call. A "fetched" event will be fired when records are successfully retrieved. If you need to constrain the query performed by fetch, you can call the query method before calling fetch.

If you'd like to only fetch specific columns, you may specify a columns property in the options for the fetch call.

The withRelated option may be specified to fetch the models of the collection, eager loading any specified relations named on the model. A single property, or an array of properties can be specified as a value for the withRelated property. The results of these relation queries will be loaded into a relations property on the respective models, may be retrieved with the related method.

collection.fetchOne([options]) → Promise<Model|null> source

Example
// select * from authors where site_id = 1 and id = 2 limit 1;
new Site({id:1})
  .authors()
  .query({where: {id: 2}})
  .fetchOne()
  .then(function(model) {
    // ...
  });
Parameters
  • [options] Object
    • [require=false] Boolean

      If true, will reject the returned response with a NotFoundError if no result is found.

    • [columns='*'] string|string[]

      Limit the number of columns fetched.

    • [transacting] Transaction

      Optionally run the query in a transaction.

    • [lock] string

      Type of row-level lock to use. Valid options are forShare and forUpdate. This only works in conjunction with the transacting option, and requires a database that supports it.

Throws
Model.NotFoundError
Returns
Promise<Model|null>

A promise resolving to the fetched model or null if none exists.

Fetch and return a single model from the collection, maintaining any relation data from the collection, and any query parameters that have already been passed to the collection. Especially helpful on relations, where you would only like to return a single model from the associated collection.

collection.findWhere()Model source

Returns
Model

The first matching model.

Return the first model with matching attributes. Useful for simple cases of find.

collection.get()Model source

Example
const book = library.get(110);
Returns
Model

The model, or undefined if it is not in the collection.

Get a model from a collection, specified by an id, a cid, or by passing in a model.

collection.invokeThen(method, arguments) → Promise source

Parameters
  • method string

    The model method to invoke.

  • arguments mixed

    Arguments to method.

Returns
Promise

Promise resolving to array of results from invocation.

Shortcut for calling Promise.all around a Collection#invoke, this will delegate to the collection's invoke method, resolving the promise with an array of responses all async (and sync) behavior has settled. Useful for bulk saving or deleting models:

collection.invokeThen('save', null, options).then(function() {
  // ... all models in the collection have been saved
});

collection.invokeThen('destroy', options).then(function() {
  // ... all models in the collection have been destroyed
});

collection.load(relations, [options]) → Promise<Collection> source

Parameters
  • relations string|string[]

    The relation, or relations, to be loaded.

  • [options] Object

    Hash of options.

    • [transacting] Transaction
    • [lock] string

      Type of row-level lock to use. Valid options are forShare and forUpdate. This only works in conjunction with the transacting option, and requires a database that supports it.

Returns
Promise<Collection>

A promise resolving to this collection

load is used to eager load relations onto a Collection, in a similar way that the withRelated property works on fetch. Nested eager loads can be specified by separating the nested relations with '.'.

collection.off() source

Example
ships.off('fetched') // Remove the 'fetched' event listener
See

collection.on() source

Example
const ships = new bookshelf.Collection;
ships.on('fetched', function(collection, response) {
  // Do something after the data has been fetched from the database
})
See

collection.once(nameOrNames, callback) source

Parameters
  • nameOrNames string

    The name of the event or space separated list of events to register a callback for.

  • callback function

    That callback to invoke only once when the event is fired.

Just like Events#on, but causes the bound callback to fire only once before being removed. Handy for saying "the next time that X happens, do this". When multiple events are passed in using the space separated syntax, the event will fire once for every event you passed in, not once for a combination of all events.

collection.orderBy(sort, order) source

Example
Cars.forge().orderBy('color', 'ASC').fetch()
   .then(function (rows) { // ...
Parameters
  • sort string

    Column to sort on

  • order string

    Ascending ('ASC') or descending ('DESC') order

Since
  • 0.9.3

Specifies the column to sort on and sort order.

The order parameter is optional, and defaults to 'ASC'. You may also specify 'DESC' order by prepending a hyphen to the sort column name. orderBy("date", 'DESC') is the same as orderBy("-date").

Unless specified using dot notation (i.e., "table.column"), the default table will be the table name of the model orderBy was called on.

collection.parse(resp) source

Parameters
  • resp Object[]

    Raw database response array.

The parse method is called whenever a collection's data is returned in a fetch call. The function is passed the raw database response array, and should return an array to be set on the collection. The default implementation is a no-op, simply passing through the JSON response.

collection.pluck() → mixed[] source

Returns
mixed[]

An array of attribute values.

Pluck an attribute from each model in the collection.

collection.pop() source

Remove a model from the end of the collection.

collection.push(model)Collection source

Parameters
  • model Object[]|Model[]|Object|Model

    One or more models or raw attribute objects.

Returns
Collection

Self, this method is chainable.

Add a model to the end of the collection.

collection.query(arguments)Collection|QueryBuilder source

Example
let qb = collection.query();
    qb.where({id: 1}).select().then(function(resp) {
      // ...
    });

collection.query(function(qb) {
  qb.where('id', '>', 5).andWhere('first_name', '=', 'Test');
}).fetch()
  .then(function(collection) {
    // ...
  });

collection
  .query('where', 'other_id', '=', '5')
  .fetch()
  .then(function(collection) {
    // ...
  });
Parameters
  • arguments function|Object|string

    The query method.

See
Returns
Collection|QueryBuilder

Will return this model or, if called with no arguments, the underlying query builder.

query is used to tap into the underlying Knex query builder instance for the current collection. If called with no arguments, it will return the query builder directly. Otherwise, it will call the specified method on the query builder, applying any additional arguments from the collection.query call. If the method argument is a function, it will be called with the Knex query builder as the context and the first argument.

collection.reduceThen(iterator, initialValue, context) → Promise source

Parameters
See
Returns
Promise

Promise resolving to the single result from the reduction.

Iterate over all the models in the collection and reduce this array to a single value using the given iterator function.

collection.remove(models, options)Model|Model[] source

Parameters
  • models Model|Model[]

    The model, or models, to be removed.

  • options Object
Returns
Model|Model[]

The same value passed as models argument.

Remove a model (or an array of models) from the collection, but does not remove the model from the database, use the model's destroy method for this.

collection.reset(models, options)Model[] source

Parameters
  • models Object[]|Model[]|Object|Model

    One or more models or raw attribute objects.

  • options Object

    See add.

Returns
Model[]

Array of models.

Adding and removing models one at a time is all well and good, but sometimes you have so many models to change that you'd rather just update the collection in bulk. Use reset to replace a collection with a new list of models (or attribute hashes). Calling collection.reset() without passing any models as arguments will empty the entire collection.

collection.resetQuery()Collection source

Returns
Collection

Self, this method is chainable.

Used to reset the internal state of the current query builder instance. This method is called internally each time a database action is completed by Sync.

collection.serialize([options]) → Object source

Parameters
  • [options] Object
    • [shallow=false] Boolean

      Exclude relations.

    • [omitPivot=false] Boolean

      Exclude pivot values.

    • [omitNew=false] Boolean

      Exclude models that return true for isNew.

Returns
Object

Serialized model as a plain object.

Return a raw array of the collection's attributes for JSON stringification. If the models have any relations defined, this will also call toJSON on each of the related objects, and include them on the object unless {shallow: true} is passed as an option.

serialize is called internally by toJSON. Override this function if you want to customize its output.

collection.set(models, [options])Collection source

Example
var vanHalen = new bookshelf.Collection([eddie, alex, stone, roth]);
vanHalen.set([eddie, alex, stone, hagar]);
Parameters
  • models Object[]|Model[]|Object|Model

    One or more models or raw attribute objects.

  • [options] Object

    Options for controlling how models are added or removed.

    • [add=true] Boolean

      If set to true it will add any new models to the collection, otherwise any new models will be ignored.

    • [merge=true] Boolean

      If set to true it will merge the attributes of duplicate models with the attributes of existing models in the collection, otherwise duplicate models in the list will be ignored.

    • [remove=true] Boolean

      If set to true any models in the collection that are not in the list will be removed from the collection, otherwise they will be kept.

Returns
Collection

Self, this method is chainable.

The set method performs a smart update of the collection with the passed model or list of models by following the following rules:

  • If a model in the list isn't yet in the collection it will be added
  • if the model is already in the collection its attributes will be merged
  • if the collection contains any models that aren't present in the list, they'll be removed.

If you'd like to customize the behavior, you can do so with the add, merge and remove options.

Since version 0.14.0 if both remove and merge options are set to false, then any duplicate models present will be added to the collection, otherwise they will either be removed or merged, according to the chosen option.

collection.shift() source

Remove a model from the beginning of the collection.

collection.slice() source

Slice out a sub-array of models from the collection.

collection.through(Interim, [throughForeignKey], [otherKey], [throughForeignKeyTarget], [otherKeyTarget])Collection source

Parameters
  • Interim Model

    Pivot model.

  • [throughForeignKey] string

    Foreign key in this collection model. By default, the foreignKey is assumed to be the singular form of the Target model's tableName, followed by _id / _{{idAttribute}}.

  • [otherKey] string

    Foreign key in the Interim model. By default, the otherKey is assumed to be the singular form of this model's tableName, followed by _id / _{{idAttribute}}.

  • [throughForeignKeyTarget] string

    Column in the Target model which throughForeignKey references, if other than Target model's id / idAttribute.

  • [otherKeyTarget] string

    Column in this collection model which otherKey references, if other than id / idAttribute.

Returns
Collection

Used to define passthrough relationships - hasOne, hasMany, belongsTo or belongsToMany, "through" an Interim model or collection.

collection.toJSON(Options) source

Parameters

Called automatically by JSON.stringify. To customize serialization, override serialize.

collection.trigger() source

Example
ships.trigger('fetched')
See

collection.triggerThen(name, [args]) source

Parameters
  • name string

    The event name, or a whitespace-separated list of event names, to be triggered.

  • [args] mixed

    Arguments to be passed to any registered event handlers.

Returns

Promise A promise resolving the the resolved return values of any triggered handlers.

A promise version of Events#trigger, returning a promise which resolves with all return values from triggered event handlers. If any of the event handlers throw an Error or return a rejected promise, the promise will be rejected. Used internally on the "creating", "updating", "saving", and "destroying" events, and can be helpful when needing async event handlers (e.g. for validations).

collection.unshift() source

Add a model to the beginning of the collection.

collection.updatePivot(attributes, [options]) → Promise source

Parameters
  • attributes Object

    Values to be set in the update query.

  • [options] Object

    A hash of options.

    • [query] function|Object

      Constrain the update query. Similar to the method argument to Model#query.

    • [require=false] Boolean

      Causes promise to be rejected with an Error if no rows were updated.

    • [transacting] Transaction

      Optionally run the query in a transaction.

Returns
Promise

A promise resolving to number of rows updated.

The updatePivot method is used exclusively on belongsToMany relations, and allows for updating pivot rows on the joining table.

This method (along with Collection#attach and Collection#detach) are mixed in to a Collection when returned by a belongsToMany relation.

collection.where()Model[] source

Returns
Model[]

Array of matching models.

Return models with matching attributes. Useful for simple cases of filter.

collection.withPivot(columns)Collection source

Parameters
  • columns string[]

    Names of columns to be included when retrieving pivot table rows.

Returns
Collection

Self, this method is chainable.

The withPivot method is used exclusively on belongsToMany relations, and allows for additional fields to be pulled from the joining table.

var Tag = bookshelf.Model.extend({
  comments: function() {
    return this.belongsToMany(Comment).withPivot(['created_at', 'order']);
  }
});

Lodash Methods

Type Definitions

reduceThenIterator(acumulator, model, index, length) source

Parameters
  • acumulator mixed
  • model Model

    The current model being iterated over.

  • index Number
  • length Number

    Total number of models being iterated over.

This iterator is used by the reduceThen method to ietrate over all models in the collection.

Events

collection.on("fetched", (collection, response, options) => source

Parameters
  • collection Collection

    The collection performing the Collection#fetch.

  • response Object

    Knex query response.

  • options Object

    Options object passed to fetch.

Tutorials
Returns
Promise

Fired after a fetch operation. A promise may be returned from the event handler for async behaviour.

Events

Construction

new Events() source

Base Event class inherited by Model and Collection. It's not meant to be used directly, and is only displayed here for completeness.

Methods

events.off(nameOrNames) source

Parameters
  • nameOrNames string

    The name of the event or space separated list of events to stop listening to.

Remove a previously-bound callback event listener from an object. If no event name is specified, callbacks for all events will be removed.

events.on(nameOrNames, callback) source

Parameters
  • nameOrNames string

    The name of the event or space separated list of events to register a callback for.

  • callback function

    That callback to invoke whenever the event is fired.

Register an event listener. The callback will be invoked whenever the event is fired. The event string may also be a space-delimited list of several event names.

events.once(nameOrNames, callback) source

Parameters
  • nameOrNames string

    The name of the event or space separated list of events to register a callback for.

  • callback function

    That callback to invoke only once when the event is fired.

Just like Events#on, but causes the bound callback to fire only once before being removed. Handy for saying "the next time that X happens, do this". When multiple events are passed in using the space separated syntax, the event will fire once for every event you passed in, not once for a combination of all events.

events.trigger(nameOrNames, [args]) source

Parameters
  • nameOrNames string

    The name of the event to trigger. Also accepts a space separated list of event names.

  • [args] mixed

    Extra arguments to pass to the event listener callback function.

Trigger callbacks for the given event, or space-delimited list of events. Subsequent arguments to trigger will be passed along to the event callback.

events.triggerThen(name, [args]) source

Parameters
  • name string

    The event name, or a whitespace-separated list of event names, to be triggered.

  • [args] mixed

    Arguments to be passed to any registered event handlers.

Returns

Promise A promise resolving the the resolved return values of any triggered handlers.

A promise version of Events#trigger, returning a promise which resolves with all return values from triggered event handlers. If any of the event handlers throw an Error or return a rejected promise, the promise will be rejected. Used internally on the "creating", "updating", "saving", and "destroying" events, and can be helpful when needing async event handlers (e.g. for validations).