May 18, 2015
Table of contents:
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.
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.
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
This should create a new posts.js
file under the models
directory:
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.
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 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.
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"),
});
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"),
});
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')
});
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.