Models

Models are the backbone of Bookshelf. They encapsulate most of the functionality that you'll need to work with your data.

Creating your own Models

To create your models you should use the bookshelf.model method and add any methods and relations that are needed. The first argument to model() should be a string, defining the model's name. The second is an object with the instance methods and properties you want to set on your model, and the third argument is only used if you want to add static methods and properties.

The following example sets up a new model that could be used to manage customer sessions on a website.

const Promise = require('bluebird')
const bcrypt = Promise.promisifyAll(require('bcrypt'))

// Defining our Customer model
const Customer = bookshelf.model('Customer', {
  // Instance properties and methods are defined here
  tableName: 'customers',

  account() {
    // This establishes a relation with the Account model
    return this.belongsTo('Account')
  }
}, {
  // Static class properties and methods
  login: Promise.method((email, password) => {
    return new this({email})
      .fetch()
      .tap((customer) => {
        return bcrypt.compareAsync(password, customer.get('password'))
          .then((valid) => {
            if (!valid) throw new Error('Invalid password')
          })
      })
  })
})

This model could then be used in a controller to login the customer like this:

const Customer = bookshelf.model('Customer')

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

Note that this would return the entire customer object including the password. This is usually not desirable, so in actual production applications you should use the model's Model#hidden or Model#visible properties to hide certain attributes when serializing the model.

Validation

There is no built-in way to validate your models before saving them to the database. However you can use any third-party validation library and it should be relatively easy to integrate. Here's an example using checkit:

const checkit = require('checkit')

const Customer = bookshelf.model('Customer', {
  initialize() {
    this.constructor.__super__.initialize.apply(this, arguments)
    this.on('saving', this.validateSave)
  },

  validateSave() {
    return checkit(rules).run(this.attributes)
  }
})

Events

There are several events fired by models at different stages of the query request process. For more information about this see the Events guide.

Note: This section of the documentation is still a WIP. For more in-depth information about models check out the API Reference.

More details about this topic on the following sections: