loopback/node_modules/model/README.md

7.0 KiB

model

About

A Model represents the data of your application. Asteroid Models are mostly used for validating interactions with a DataSource. Usually your models will correspond to a namespace in your data source (database table, http url, etc). The bulk of your application's business logic will be in your Model or Node.js scripts that require your model.

Data Definition Language

TODO ~ document

API

Defining Models

The following assumes your have reference to a class that inherits from Model. The simplest way to get this is by using the app API.

// define a model class using the app api
var Color = app.define('color');

// provide an exact plural name
var Color = app.define('color', {plural: 'colors'});

Note: If a plural name is not defined, the model will try to pluralize the singular form.

MyModel.defineSchema(schema)

Define the data the model represents using the data definition language.

// define the color model
var Color = app.define('color');

// define the schema for the Color model
Color.defineSchema({
  name: 'string',
  id: 'uid',
  tweets: 'array'
});
MyModel.dataSource(name, namespace)

Set the data source for the model. Must provide a name of an existing data source. If the namespace is not provided the plural model name (eg. colors) will be used.

// set the data source
Color.dataSource('color-db', 'COLOR_NAMES');

Note: If you do not set a data source or a map (or both) the default data source will be used (an in memory database).

MyModel.defineMap(map)

Define a mapping between the data source representation of your data and your app's representation.

// manually map Color to existing table columns
Color.defineMap({
  dataSource: 'color-db', // optional, will use model's data source
  table: 'COLOR_NAMES', // required
  map: { // optional if schema defined
    id: 'COLOR_ID',
    name: 'COLOR_NAME'
  }
});

// mix in a mapping from another data source
Color.defineMap({
  dataSource: 'twitter',
  url: function(color) {
    return '/search?limit=5&q=' + color.name;
  },
  map: {
    // provides the color.tweets property
    tweets: function(tweets) {
      return tweets;
    }
  }
});

Note: You may define multiple maps for a single model. The model will combine the data for you.

MyModel.discoverSchema(fn)

Using the mapped data source, try to discover the schema of a table or other namespace (url, collection, etc).

// use existing schema to map to desired properties
Color.dataSource('color-db', 'COLOR_NAMES');
Color.discoverSchema(function (err, oracleSchema) {
  var schema = {tweets: 'array'};
  var map = {dataSource: 'color-db', table: 'COLOR_NAMES'};

  // inspect the existing table schema to create a mapping
  Object
    .keys(oracleSchema)
    .forEach(function (oracleProperty) {
      // remove prefix
      var property = oracleProperty.toLowerCase().split('_')[0];
   
      // build new schema
      schema[property] = oracleProperty[oracleProperty];
      // create mapping to existing schema
      map[property] = oracleProperty;
    });
 
  Color.defineSchema(schema);  
  Color.defineMap(map);
});

Custom Methods

There are two types of custom methods. Static and instance.

Static

Static methods are available on the Model class itself and are used to operate on many models at the same time.

Instance

Instance methods are available on an instance of a Model and usually act on a single model at a time.

Defining a Static Method

The following example shows how to define a simple static method.

Color.myStaticMethod = function() {
  // only has access to other static methods
  this.find(function(err, colors) {
    console.log(colors); // [...] 
  });
}

Defining an Instance Method

The following is an example of a simple instance method.

Color.prototype.myInstanceMethod = function() {
  console.log(this.name); // red
}

Remotable Methods

Both types of methods may be set as remotable as long as they conform to the remotable requirements. Asteroid will expose these methods over the network for you.

Remotable Requirements

Static and instance methods must accept a callback as the last argument. This callback must be called with an error as the first argument and the results as arguments afterward.

You must also define the input and output of your remoteable method. Describe the input or arguments of the function by providing an accepts array and describe the output by defining a returns array.

// this method meets the remotable requirements
Color.getByName = function (name, callback) {
  Color.find({where: {name: name}}, function (err, colors) {
    // if an error occurs callback with the error
    if(err) {
      callback(err);
    } else {
      callback(null, colors);
    }
  });
}

// accepts a name of type string
Color.getByName.accepts = [
  {arg: 'name', type: 'String'} // data definition language
];

// returns an array of type Color
Color.getByName.returns = [
  {arg: 'colors', type: ['Color']} // data definition language
];

Note: any types included in accepts/returns must be native JavaScript types or Model classes.

Working with Models

The following assumes you have access to an instance of a Model class.

// define a model 
var Color = app.define('color');

// create an instance
var color = new Color({name: red});

myModel.save([options], [callback])

Remoteable

Save the model using its configured data source.

var color = new Color();
color.name = 'green';

// fire and forget
color.save();

// callback
color.save(function(err, color) {
  if(err) {
    console.log(err); // validation or other error
  } else {
    console.log(color); // updated with id
  }
});

myModel.destroy([callback])

Remoteable

Delete the instance using attached data source. Invoke callback when ready.

var color = Color.create({id: 10});

color.destroy(function(err) {
  if(err) {
    console.log(err); // could not destroy
  } else {
    console.log('model has been destroyed!');
  }
});

MyModel.all()

MyModel.find()

MyModel.count()

Model Relationships

Config

Options

namespace

A table, collection, url, or other namespace.

properties

An array of properties describing the model's schema.

"properties": [
    {
      "name": "title",
      "type": "string"
    },
    {
      "name": "done",
      "type": "boolean"
    },
    {
      "name": "order",
      "type": "number"
    }
  ]
}

Dependencies

data source

The name of a data source data-source for persisting data.