Today we are going to look at creating and up dating records with Ember. We are going to be using our School Directory App that we have been iterating on for a while now. If you haven't already start by cloning that repo and getting it running locally. If you have already been building out that repo in the past week, it might still be helpful to update it as I had to add a few preliminary items in preparation for setting up editing (really just a few styles and a mirage route for PATCH).
Let's get started.
ember s
Now we can visit our site just to re-familiarize ourself with it. What we are
going to want to do first in create the ability to edit an athlete. Let's do
this by first creating an edit route that is a child of
contacts.contact
route.
ember g route contacts/contact/edit
Now, let's pull our
additionalInformationComponent
out of the contact-card
component and put it in our contact controller and template.
First, let remove the component from the contact-card template. In
app/templates/components/contact-card.hbs
remove
{{component
additionalInformationComponent contact=contact}}
and paste that in
app/templates/contacts/contact.hbs
. And in the contact template we will change
the
contact=contact
to
contact=model
. Then we need to move the
additionalInformationComponent
computed property from
app/components/contact-card.js
to
app/controllers/contacts/contact.js
. Here
again we will change any occurrence of
contact
to
model
.
import Ember from 'ember';
export default Ember.Controller.extend({
additionalInformationComponent: Ember.computed('model.isTeacher', function(){
if(this.get('model.isTeacher')){
return 'past-education';
} else {
return 'current-courses';
}
})
});
Now if we look back at our site at
http://localhost:4200
everything is working
again. One final preliminary: we need to move our contact card into the
contact/index template at
app/templates/contacts/contact/index.hbs
. And
finally add an outlet to
app/templates/contacts/contact.hbs
.
Now, we are ready to start implementing our edit. The first thing to note, if you don't specify a model on a route, it gets its parents model. So for index and edit we don't need to specify the model as we already have it on the contact route. To edit our model we are going to use an addon from Dockyard called ember-changeset . There is a link in the episode script. This addon, which is inspired by Elixir's database wrapper, ecto, allows us to edit a contact without making changes directly on the model. This can prevent our model from being placed in a dirty state while editing, and it makes rollbacks a lot easier. It would also allow us to validate our changes before they get set on the model. We aren't going to do validations today, but we can in the future.
We will start by installing the addon. And generating an edit component.
ember install ember-changeset
ember g component edit-card
Now we should restart our server so we can have access to the changeset helper that we will use.
Then let's open up out edit template and add our newly created component. As we are going to be using the changeset addon we will have a few actions that we will call from our component:
app/templates/contacts/contact/edit.hbs
{{edit-card changeset=(changeset model)
submit=(action "submit")
rollback=(action "rollback") }}
Now, in our edit controller, let's go ahead and set up our actions for saving
and rolling back our edit changes. Open up
app/controllers/contacts/contact/edit.js
: Let's create a submit action that
will take a changeset as the param, and will call save on that changeset. and
transition back to the
contacts/contact/index
route. Then, let's add a
rollback action which just calls rollback on the changeset.
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
submit(changeset) {
return changeset.save().then(()=>{
this.transitionToRoute('contacts.contact.index');
});
},
rollback(changeset) {
return changeset.rollback();
}
}
});
Now, we can set up our component. First, let's give our component a class of card and a class edit-card.
import Ember from 'ember';
export default Ember.Component.extend({
classNames: ['card', 'edit-card']
});
All that is left is for us to set up our component's template.
Then let's open up our component's template and setup our edit form.
{{link-to 'back to contact' 'contacts.contact' class='pull-right'}}
<form>
<div class="form-group">
<label>First Name: </label>{{input class="form-control" value=changeset.firstName}}
</div>
<div class="form-group">
<label>Last Name: </label>{{input class="form-control" value=changeset.lastName}}
</div>
<div class="form-group">
<label>Email: </label>{{input class="form-control" value=changeset.email}}
</div>
<div class="form-group">
<label>Phone: </label>{{input class="form-control" value=changeset.phone}}
</div>
<div class="form-group">
<label>Title: </label>{{input class="form-control" value=changeset.title}}
</div>
<div class="form-group">
<label>Avatar: </label>{{input class="form-control" value=changeset.avatar}}
</div>
<button class="btn btn-primary" {{action submit changeset}}>Submit</button>
<button class="btn btn-primary" {{action rollback changeset}}>Rollback</button>
</form>
One last thing. In our contact-card template we need to add a link to our edit
form. At the bottom of the template in
app/templates/components/contact-card.hbs
just add:
{{link-to 'Edit' 'contacts.contact.edit'}}
That does it, we now have a working edit form. Tomorrow we will look at validating our edits.
Comments for Creating and Updating Records