# Model: Getting Started

A model defines an entity schema that will be handled by Vuex ORM. You can visualize a model as a table definition in a database. You can use models wherever your application needs to manage a collection of entities, whether they actually correspond to a database or not. Models encapsulate most of the functionality that you'll need to work with your data.

# Defining A Model

You can create a model by defining a new class that extends the Vuex ORM base Model. All models require two static properties, an entity and fields property.

The following example sets up a new model that can be used to manage users:

import { Model } from '@vuex-orm/core'

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      id: this.attr(null),
      name: this.attr('John Doe')
    }
  }
}

# Entity

entity is a property that identifies a model, similar to the name of a database table. Each model's entity name must be unique!

All models will create a Vuex module by their entity property and are found in state.entities. In our example above, we will have created state.entities.users. The default namespace entities can be configured during installation.

# Fields

fields is a required property method that returns an object of field attributes to the model's schema. It maps data to their respective fields. It should return an object of key-value pairs consisting of the field name , and attribute definitions.

# Field Attributes

Vuex ORM supports the most common Javascript datatypes including primitives, object literals, and arrays. These datatypes are defined using various field attributes. The most common type of attribute you'll come across is the generic attribute type.

Attributes take a single argument – the fields default value. This default value is used in the event the field is missing when inserting data.

Attribute Decorators

Typescript users can define attributes using decorators. To learn more about these, please take a look at the Decorators section.

# Generic Type

Generic attributes can be defined using this.attr(...). This type of attribute, unlike other attributes, will take any datatype as it's default value, including String, Number, Boolean, Object and Array.

The following example defines id and name fields on a user model using the generic attribute type:

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      id: this.attr(null),
      name: this.attr('John Doe')
    }
  }
}

# string Type

String attributes can be defined using this.string(...). This type of attribute provides casting and will convert any given value to String. The default value can be any string, including an empty string.

The following example defines the name field on a user model using the string attribute:

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      ...
      name: this.string('')
    }
  }
}

This attribute will ensure a given value is cast as a string. For example, if name receives a value of false or null, it will become 'false' or 'null'.

This attribute may also have null as a default value. However, to prevent casting, you will want to chain nullable() to ensure the value can be set appropriately.

{
  ...
  name: this.string(null).nullable()
}

# number Type

Number attributes can be defined using this.number(...). This type of attribute provides casting and will convert any given value to Number. The default value can be any integer.

The following example defines the id field on a user model using the number attribute:

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      id: this.number(0)
      ...
    }
  }
}

This attribute will ensure a given value is cast as a number. For example, if id receives a value of false, it will become 0, null will become 0, '123' will become 123, and so on.

This attribute may also have null as a default value. However, to prevent casting, you will want to chain nullable() to ensure the value can be set appropriately.

{
  ...
  name: this.number(null).nullable()
}

# boolean Type

Boolean attributes can be defined using this.boolean(...). This type of attribute provides casting and will convert any given value to Boolean. The default value can be either true or false.

The following example defines the active field on a user model using the boolean attribute:

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      ...
      active: this.boolean(false)
    }
  }
}

This attribute will ensure a given value is cast as a boolean. Any truthy or falsy value will be cast accordingly. For example, if active receives a value of 0 or null, it will become false. Likewise, if it receives a value of 1 or 'yes' (non-empty string) it will become true.

This attribute may also have null as a default value. However, to prevent casting, you will want to chain nullable() to ensure the value can be set appropriately.

{
  ...
  active: this.boolean(null).nullable()
}

# Special Attributes

# uid Type

UID attribute is the special attribute that works similarly to "Autoincrement" column type in RDB. When you try to save a record without the value set to the UID field, it will generate a unique ID automatically.

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      id: this.uid(),
      name: this.string('')
    }
  }
}

This attribute will generate a unique string value using the uuid (opens new window) package with v1 method that looks something like 2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d.

const user = store.$repo(User).make()

user.id // <- '2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d'

# Defining Relations

You can define a relationship between different models using relation attributes such as this.hasMany, this.belongsTo, etc. To learn more about these, please take a look at Relationships page.

# Primary Key

All models must have a primary key field. The primary key serves as an index key that Vuex ORM will use to persist entities to the store by it's value.

By default, Vuex ORM will look for a primary key field called id.

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      id: this.attr(null)
      ...
    }
  }
}

# Custom Primary Key

The primary key can be mapped to any field that will have a unique value by defining the static primaryKey property on a model.

The following example configures a user model to identify the field myId as the primary key:

class User extends Model {
  static entity = 'users'

  static primaryKey = 'myId'

  static fields () {
    return {
      myId: this.attr(null)
      ...
    }
  }
}

# Missing Primary Key

If a model is missing a primary key field definition, Vuex ORM will generate a primary key field automatically during database registration. The generated field will be configured using the uid attribute type and named id unless the static primaryKey property is defined on a model.

The following example sets up a user model without an id primary key field:

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      name: this.attr('')
    }
  }
}

Vuex ORM will recognize the model is missing an id field and will generate one in it's absence. The model will now be configured as follows:

class User extends Model {
  static entity = 'users'

  static fields () {
    return {
      id: this.uid(), // The auto-generated primary key field.
      name: this.attr('')
    }
  }
}

The same principle applies to a model with a custom primary key definition. Vuex ORM will generate a primary key field using the name defined as the static primaryKey property.

The following example sets up a user model configured with a primaryKey property but without a corresponding primary key field:

class User extends Model {
  static entity = 'users'

  static primaryKey = 'myId'

  static fields () {
    return {
      name: this.attr('')
    }
  }
}

Vuex ORM will recognize a custom primaryKey has been defined but is unable to locate the corresponding field definition, and will generate one in it's absence. The model will now be configured as follows:

class User extends Model {
  static entity = 'users'

  static primaryKey = 'myId'

  static fields () {
    return {
      myId: this.uid(), // The auto-generated custom primary key field.
      name: this.attr('')
    }
  }
}