Defining Models in Ember Data

A model is a class that defines the properties and behaviour of an object that is persisted as part of your application.

The model is the blueprint for how each record should be created.

If you’re familiar with Object-relational mapping, the concept of a model should already be pretty familiar to you.

In today’s tutorial we’ll be looking at defining models to use as part of Ember Data.

What is a Model?

I don’t want to jump ahead and make assumptions that you already know what a model is, so first we’ll look into exactly what is a model.

A model is a blueprint that describes how a particular object should be created. This will typically include what properties and relationships the model should have.

For example, a Post model might have properties such as title, body and published_at, and a comments relationship.

When you retrieve an individual post from your JSON API, the model definition will be used to create new record objects that you can work with.

I think it’s best to think about models as simply the blueprints for record objects.

Generating a new Model

As we’ve seen a couple of times over the last couple of weeks, by using Ember CLI we can cut out a lot of the boilerplate work and use the default generators to create new files for us.

To create a new Model we can use the following command:

ember g model post  
[/bash]

This should create a new `posts.js` file under the `models` directory:  
```js  
import DS from ’ember-data’;

export default DS.Model.extend({

});  

This is your basic model definition. As you can see we extend the DS.Model Ember class.

Defining attributes

The first thing we need to do is to define the attributes of the model:

import DS from ’ember-data’;

export default DS.Model.extend({  
title: DS.attr(‘string’),  
body: DS.attr(‘string’),  
published_at: DS:attr(‘date’)  
});  

Defining the attributes is really easy as you all you have to do is list each as a property of the class.

The argument to the attr() method is optional. By default, Ember will assume the attribute type from the JSON response. However you can ensure that the correct type is used by defining it in your model.

Finally, you can also set defaults for each of your attributes by passing an optional object as the second parameter:

import DS from ’ember-data’;

export default DS.Model.extend({  
title: DS.attr(‘string’),  
body: DS.attr(‘string’),  
published_at: DS.attr(‘date’),  
is_draft: DS.attr(‘bool’, {defaultValue: true})  
});  

Defining relationships

Defining model relationships is a bit more tricky because you need to understand the structure of your data. If you don’t already have a good idea of how your data needs to be structured, it’s probably a sign that you need to go back and talk to the stakeholders of the application.

One-to-One

For One-to-One relationships, you can use the belongsTo() method:

import DS from ’ember-data’;

export default DS.Model.extend({  
summary: DS.belongsTo(‘summary’)  
});  

One-to-Many

For One-to-Many relations, you can use the hasMany() method:

import DS from ’ember-data’;

export default DS.Model.extend({  
comments: DS.hasMany(‘comment’)  
});  

To define the inverse of this relationship in the Comment Model you would use the belongsTo() method:

import DS from ’ember-data’;

export default DS.Model.extend({  
post: DS.belongsTo(‘post’)  
});  

Many-to-Many

And finally, to define a Many-to-Many relationship you would use the hasMany() method in both Models.

The Post Model would look like:

import DS from ’ember-data’;

export default DS.Model.extend({  
tags: DS.hasMany(‘tag’)  
});  

And the Tag Model would look like:

import DS from ’ember-data’;

export default DS.Model.extend({  
posts: DS.hasMany’post’)  
});  

Conclusion

If you’ve used something like Laravel’s Eloquent, or Rails’ ActiveRecord this will probably be familiar to you.

Models are an important part of your application because this is typically where you encapsulate the logic concerning persisted data.

Ember Data looks and feels very similar to an ORM library. As we continue in this deep dive of Ember.js, we will explore further into using models as part of a bigger application.