Edit Page

Attributes

Overview

Model attributes are basic pieces of information about a model. A model called Person might have attributes called firstName, lastName, phoneNumber, age, birthDate and emailAddress.

Attribute Options

These options can be used to enforce various constraints and add special enhancements to our model attributes.

type

Specifies the type of data that will be stored in this attribute. One of:

  • string
  • text
  • integer
  • float
  • date
  • datetime
  • boolean
  • binary
  • array
  • json
  • mediumtext
  • longtext
  • objectid
  • email
defaultsTo

When a record is created, if no value was supplied, the record will be created with the specified defaultsTo value. The supplied value can also be a function that waterline will run while creating the record.

attributes: {
  phoneNumber: {
    type: 'string',
    defaultsTo: '111-222-3333'
  },
  orderNumber: {
    type: 'text',
    defaultsTo: function() {
      return uuid.v4();
    }
  }
}
autoIncrement

Sets up the attribute as an auto-increment key. When a new record is added to the model, if a value for this attribute is not specified, it will be generated by incrementing the most recent record's value by one. Note: Attributes which specify autoIncrement should always be of type: 'integer'. Also, bear in mind that the level of support varies across different datastores. For instance, MySQL will not allow more than one auto-incrementing column per table.

attributes: {
  placeInLine: {
    type: 'integer',
    autoIncrement: true
  }
}
unique

Ensures no two records will be allowed with the same value for the target attribute. This is an adapter-level constraint, so in most cases this will result in a unique index on the attribute being created in the underlying datastore.

attributes: {
  username: {
    type: 'string',
    unique: true
  }
}

When using MySQL with the utf8mb4 character set, you will need to add the size constraint to the appropriate column in your table directly via MySQL. Otherwise, since type: 'string' is translated to varchar(255) in the MySQL adapter, the unique: true constraint will cause an 'index too long' error: ER_INDEX_COLUMN_TOO_LONG: Index column size too large. The maximum column size is 767 bytes.

primaryKey

Use this attribute as the the primary key for the record. Only one attribute per model can be the primaryKey. Note: This should never be used unless autoPK is set to false.

attributes: {
  uuid: {
    type: 'string',
    primaryKey: true,
    required: true
  }
}
enum

A special validation property which only saves data which matches a whitelisted set of values.

attributes: {
  state: {
    type: 'string',
    enum: ['pending', 'approved', 'denied']
  }
}
size

If supported in the adapter, can be used to define the size of the attribute. For example in MySQL, size can be specified as a number (n) to create a column with the SQL data type: varchar(n).

attributes: {
  name: {
    type: 'string',
    size: 24
  }
}
columnName

Inside an attribute definition, you can specify a columnName to force Sails/Waterline to store data for that attribute in a specific column in the configured connection (i.e. database). Be aware that this is not necessarily SQL-specific-- it will also work for MongoDB fields, etc.

While the columnName property is primarily designed for working with existing/legacy databases, it can also be useful in situations where your database is being shared by other applications, or you don't have access permissions to change the schema.

To store/fetch your model's numberOfWheels attribute into/from the number_of_round_rotating_things column:

// An attribute in one of your models:
  // ...
  numberOfWheels: {
    type: 'integer',
    columnName: 'number_of_round_rotating_things'
  }
  // ...

Now for a more thorough/realistic example.

Let's say you have a User model in your Sails app that looks like this:

// api/models/User.js
module.exports = {
  connection: 'shinyNewMySQLDatabase',
  attributes: {
    name: {
      type: 'string'
    },
    password: {
      type: 'string'
    },
    email: {
      type: 'email',
      unique: true
    }
  }
};

Everything works great, but instead of using an existing MySQL database sitting on a server somewhere that happens to house your app's intended users:

// config/connections.js
module.exports = {
  // ...

  // Existing users are in here!
  rustyOldMySQLDatabase: {
    adapter: 'sails-mysql',
    user: 'bofh',
    host: 'db.eleven.sameness.foo',
    password: 'Gh19R!?had9gzQ#Q#Q#%AdsghaDABAMR>##G<ADMBOVRH@)$(HTOADG!GNADSGADSGNBI@(',
    database: 'jonas'
  },
  // ...
};

Let's say there's a table called our_users in the old MySQL database that looks like this:

the_primary_key email_address full_name seriously_encrypted_password
7 [email protected] Mike McNeil ranchdressing
14 [email protected] Nick Crumrine thousandisland

In order to use this from Sails, you'd change your User model to look like this:

// api/models/User.js
module.exports = {
  connection: 'rustyOldMySQLDatabase',
  tableName: 'our_users',
  attributes: {
    id: {
      type: 'integer',
      unique: true,
      primaryKey: true,
      columnName: 'the_primary_key'
    },
    name: {
      type: 'string',
      columnName: 'full_name'
    },
    password: {
      type: 'string',
      columnName: 'seriously_encrypted_password'
    },
    email: {
      type: 'email',
      unique: true,
      columnName: 'email_address'
    }
  }
};

You might have noticed that we also used the tableName property in this example. This allows us to control the name of the table that will be used to house our data.

The columnName property is not valid for plural associations (that is, attributes with their collection property set). If you’re trying to customize a join table for a many-to-many association, use the through property instead.

The columnName property is not valid for plural associations (that is, attributes with their collection property set). If you’re trying to customize a join table for a many-to-many association, use the through property instead.

Is something missing?

If you notice something we've missed or could be improved on, please follow this link and submit a pull request to the sails-docs repo. Once we merge it, the changes will be reflected on the website the next time it is deployed.

Sails logo
  • Home
  • Get started
  • Support
  • Documentation
  • Documentation

For a better experience on sailsjs.com, update your browser.

Documentation

Reference Concepts App structure | Upgrading Contribution guide | Tutorials More

Concepts

  • Assets
    • Default Tasks
    • Disabling Grunt
    • Task Automation
  • Blueprints
    • Blueprint Actions
    • Blueprint Routes
  • Configuration
    • The local.js file
    • Using `.sailsrc` Files
  • Controllers
    • Generating Controllers
    • Routing to Controllers
  • Custom Responses
    • Adding a Custom Response
    • Default Responses
  • Deployment
    • FAQ
    • Hosting
    • Scaling
  • Extending Sails
    • Adapters
      • Available Adapters
      • Custom Adapters
    • Generators
      • Available Generators
      • Custom Generators
    • Hooks
      • Hook Specification
        • .configure()
        • .defaults
        • .initialize()
        • .routes
      • Installable Hooks
      • Project Hooks
      • Using Hooks
  • File Uploads
    • Uploading to GridFS
    • Uploading to S3
  • Globals
    • Disabling Globals
  • Internationalization
    • Locales
    • Translating Dynamic Content
  • Logging
    • Custom log messages
  • Middleware
    • Conventional Defaults
  • Models and ORM
    • Associations
      • Dominance
      • Many-to-Many
      • One Way Association
      • One-to-Many
      • One-to-One
      • Through Associations
    • Attributes
    • Lifecycle callbacks
    • Model Settings
    • Models
    • Query Language
    • Validations
  • Policies
    • Sails + Passport
  • Programmatic Usage
    • Tips and Tricks
  • Realtime
    • Multi-server environments
    • On the client
    • On the server
  • Routes
    • Custom Routes
    • URL Slugs
  • Security
    • Clickjacking
    • Content Security Policy
    • CORS
    • CSRF
    • DDOS
    • P3P
    • Socket Hijacking
    • Strict Transport Security
    • XSS
  • Services
    • Creating a Service
  • Sessions
  • Testing
  • Views
    • Layouts
    • Locals
    • Partials
    • View Engines

Built with Love

The Sails framework is maintained by a web & mobile studio in Austin, TX, with the help of our contributors. We created Sails in 2012 to assist us on Node.js projects. Naturally we open-sourced it. We hope it makes your life a little bit easier!

Sails:
  • What is Sails?
  • Treeline IDE
  • Contribute
  • Logos/artwork
About:
  • The Sails Company
  • Security
  • News
  • Legal
Help:
  • Get started
  • Documentation
  • Docs
  • Enterprise
  • Hire us

© 2012-2018 The Sails Company. 
The Sails framework is free and open-source under the MIT License.