Skip to content

Latest commit

 

History

History
239 lines (175 loc) · 6.75 KB

instructions.md

File metadata and controls

239 lines (175 loc) · 6.75 KB

Register provider

Make sure to register the provider inside start/app.js file.

const providers = [
  'adonis-mongoose-model/providers/MongooseProvider',
]

Config mongodb connection

Finally add the database config inside config/database.js file.

  /*
  |--------------------------------------------------------------------------
  | MongoDB
  |--------------------------------------------------------------------------
  |
  | Here we define connection settings for MongoDB database.
  |
  */
  mongodb: {
    connectionString: Env.get('MONGO_CONNECTION_STRING', null),
    connection: {
      host: Env.get('MONGO_HOST', 'localhost'),
      port: Env.get('MONGO_PORT', 27017),
      user: Env.get('MONGO_USER', 'admin'),
      pass: Env.get('MONGO_PASSWORD', ''),
      database: Env.get('MONGO_DATABASE', 'adonis'),
      options: {
        // All options can be found at http://mongoosejs.com/docs/connections.html
      },
      debug: false
    }
  },

And then your .env file

  DB_CONNECTION=mongodb
  MONGO_HOST=127.0.0.1
  MONGO_PORT=27017
  MONGO_USER=user
  MONGO_PASSWORD=pwsecret123
  MONGO_DATABASE=adonis

That's all 🎉

Configuring Auth serializer

Edit the config/auth.js file for including the serializer. For example on the api schema

  api: {
    serializer: 'mongoose',
    scheme: 'api',
    model: 'App/Models/User',
    token: 'App/Models/Token',
    uid: 'username', // The user identifier. Ej: email, username
    password: '', // Password field if using user-password validation
    expiry: '30d', // Not yet implemented
  },

There's an example of a mongoose Token Model below, that will match with the serializer perfectly. (this needs more work)

Creating Models

You can initiate a model using adonis cli,

adonis make:mongoose Foo

And that will make the following

'use strict'

const BaseModel = use('MongooseModel')

/**
 * @class Foo
 */
class Foo extends BaseModel {
  static boot ({ schema }) {
    // Hooks:
    // this.addHook('preSave', () => {})
    // Indexes:
    // this.index({}, {background: true})
    // Virtuals, etc:
    // schema.virtual('something').get(.......)
  }
  /**
   * Foo's schema
   */
  static get schema () {
    return {

    }
  }
}

module.exports = Foo.buildModel('Foo')

Defining Schema

You define your schema by overwriting the static get schema ().

Create indexes

Indexes can be created inside the static boot ({ schema }) function (using the same syntax as mongoose's) or outside the class declaration. In that case the index will be deferred until the schema is built when running buildModel

Using hooks

As you might know, Adonis comes with a tool called hook, which you can create using adonis make:hook User. That'll create a Hook for the User model so you can attach middleware straight to that. Now with mongoose-model, you can attach a middleware to a model. Adonis hook documentation - Mongoose middleware documentation

Inside the boot function, you can

static boot ({ schema }) {
  this.addHook('preSave', 'UserHook.notifyUpdate')
}

Having in App/Models/Hooks/UserHook.js:

UserHook.notifyUpdate = async (modelInstance) => {
  // Use await if you'd like to make this async
  NotificationCenter.push(modelInstance._id, 'save')
}

The addHook functionality doesn't necesarely needs a hook. You can use a callback (the mongoose's middleware doc), and the name of the hook is composed by [pre | post] [Init | Save | Remove | Validate]. It's important that the command is written in CamelCase.

Using timestamps

As default, adonis-mongoose-model comes with the created_at and updated_at property, that comes with a middleware that updates the updated_at prop each time you save.

You can ignore those properties by adding a static property on your model:

static get timestamps () {
  return false
}

Extra: accessing the raw schema

Inside the boot function you can take advantage of the { schema } passed as parameter and access the raw mongoose schema, and add all kinds of custom functionality. If you are thingking that this package is mising something, create a PR! They are more than welcome. Also, when calling buildSchema(), it returns the schema that you can now modify

Token model

When using auth, you'll need to define a Token Model. You do that on the config/auth.js file, under the token: '' property.

You'll have to create a model App/Models/Token and extend the mongoose token-model it like this:

'use strict'

const TokenMongoose = use('AdonisMongoose/Src/Token')

/**
 * Token's instance and static methods
 * @class
 */
class Token extends TokenMongoose {
  /**
   * You can modify the amount of days that the token will be valid
   */
  static expires () {
    return 5
  }

  /**
   * You can modify the default schema
   */
  static get schema () {
    // Edit your schema here
    return super.schema
  }

  /**
   * Customize populated properties for the user
   */
  static getUserFields (type) {
    return '_id email'
  }
}

module.exports = Token.buildModel('Token')

Check the full source of the Token Model here: src/Model/TokenMongoose.js

Advanced Usage

new Schema options

If you wanna add the custom schema options when initializing, you can override the static property static get schemaOptions () and return the object with the custom options. Also on static boot () you have access to the schema by doing this._schema, so you can set properties like this._schema.set(option, value)

Life Cycle

The BaseModel has a pretty simple lifecycle.

When you call buildModel('Modelname'), this steps occur:

  • The Schema is built (if you havent built it already), using the static property static get schema() and with the options from the static get schemaOptions ().

  • Now we have the schema, so the next step uses mongoose's schema.loadClass(this). This way every method is inherited on the Model.

  • Then the indexes are created (only if you've specified before the buildModel)

  • Then the boot() function is triggered, so if you'd like to add custom creation behaviour (like adding hooks or indexes) you can, overwritting this empty static method.

  • Then the model is created, using mongoose.model(name, this._schema) and returned for you to export.

About the primaryKey

Auth Serializers and Schemes need the model to have a 'primaryKey' property, so they can have the unique identifier of the model. The primaryKey of Mongoose-Model is 'id', which corresponds with this. If you'd like to change it, overwrite the property on your model.

static get primaryKey () {
  return 'id'
}