“This is the 23rd day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

We introduced Ember Data in Ember.js, along with Model Definitions and Record Queries for Ember Data. In this article, we will continue to cover record operations: creating, updating and deleting records.

Create a record

Records can be created by calling the createRecord() method in the Store.

store.createRecord('post', {
  title: 'Rails is Omakase',
  body: 'Lorem ipsum'
});
Copy the code

You can use the store object this.store in controllers and routes.

Update record

Changing an Ember Data record is as simple as setting the properties to change:

this.store.findRecord('person', 1).then(function(tyrion) { // ... after the record has loaded tyrion.firstName = 'Yollo'; });Copy the code

Continue to record

Records in Ember Data are persisted by instance. Any instance of save() is called, and the Model makes a network request.

Ember Data tracks the status of each record for you. When saved, this allows Ember Data to treat newly created records differently from existing records.

By default, Ember Data adds new records created by POST to its type URL.

let post = store.createRecord('post', {
  title: 'Rails is Omakase',
  body: 'Lorem ipsum'
});

post.save(); // => POST to '/posts'
Copy the code

The existing records on the back end are updated using the HTTP PATCH verb.

store.findRecord('post', 1).then(function(post) {
  post.title; // => "Rails is Omakase"
  post.title = 'A new post';
  post.save(); // => PATCH to '/posts/1'
});
Copy the code

You can determine if a record has unfinished changes that have not been saved by examining its hasDirtyAttributes attribute. You can also use the changedAttributes() method to see which parts of the record were changed and what the original values were. ChangedAttributes returns an object whose key is the changed attribute and whose value is an array of values [oldValue, newValue].

person.isAdmin; // => false
person.hasDirtyAttributes; // => false
person.isAdmin = true;
person.hasDirtyAttributes; // => true
person.changedAttributes(); // => { isAdmin: [false, true] }
Copy the code

At this point, you can either keep the changes or roll them back by saving (). The records saved by the rollbackAttributes() call will restore all changedAttributes to their original values. If there is a record isNew, it will be removed from the Store.

person.hasDirtyAttributes; // => true person.changedAttributes(); // => { isAdmin: [false, true] } person.rollbackAttributes(); person.hasDirtyAttributes; // => false person.isAdmin; // => false person.changedAttributes(); / / = > {}Copy the code

Handling Validation errors

If the backend server returns validation errors after trying to save, those errors will be available on the attributes of the Errors model. This is how the error may appear when saving a blog post in a blog template:

{{#each this.post.errors.title as |error|}}
  <div class="error">{{error.message}}</div>
{{/each}}
{{#each this.post.errors.body as |error|}}
  <div class="error">{{error.message}}</div>
{{/each}}
Copy the code

Promises

Save () returns a promise, which makes it easy to handle successful and failed scenarios asynchronously. This is a common pattern:

let post = store.createRecord('post', {
  title: 'Rails is Omakase',
  body: 'Lorem ipsum'
});

let self = this;

function transitionToPost(post) {
  self.transitionToRoute('posts.show', post);
}

function failure(reason) {
  // handle the error
}

post
  .save()
  .then(transitionToPost)
  .catch(failure);

// => POST to '/posts'
// => transitioning to posts.show route
Copy the code

Delete records

Deleting records is as simple as creating them. Call deleteRecord() on any instance of the model. This marks the record as deleted. The delete can then be persisted using save(). Alternatively, you can use the destroyRecord method to both delete and persist.

let post = store.peekRecord('post', 1);
  post.deleteRecord();
  post.isDeleted; // => true
  post.save(); // => DELETE to /posts/1
});

// OR
  post = store.peekRecord('post', 2);
  post.destroyRecord(); // => DELETE to /posts/2
});
Copy the code