Skip to content

Tutorial app showing ember crud and mirage best practices

Notifications You must be signed in to change notification settings

jkubaile/ember-crud-mirage-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Crud

This README outlines the details of collaborating on this Ember application. A short introduction of this app could easily go here.

Prerequisites

You will need the following things properly installed on your computer.

Installation

  • git clone <repository-url> this repository
  • cd ember-crud-mirage-example
  • npm install
  • bower install

Running / Development

Code Generators

Make use of the many generators for code, try ember help generate for more details

Running Tests

  • ember test
  • ember test --server

Building

  • ember build (development)
  • ember build --environment production (production)

Deploying

Specify what it takes to deploy your app.

CRUD Application Tutorial

This tutorial application is heavily inspired by https://gist.github.com/pablobm/e77a98e5f3c610953a82

It extends the main concepts with working mirage model and endpoints. You can checkout this repository or just follow the steps below.

Step 0: create the project

  • Create a new ember project: ember new crud.

Step 1: install ember addon dependencies

  • Install mirage dependency: ember install ember-cli-mirage.
  • We use semantic ui for visualisation: ember install semantic-ui-ember.
  • Start ember with ember s and visit http://localhost:4200 with your browser.

Step 2: define the model

We are going to build a small addressbook. So we need something like an address.

  • Create the ember model: ember generate model address - this is for your ember frontend code.
  • Create the mirage model: ember generate mirage-model address - this for mirage, knowing your model.
  • Create the mirage factory: ember generate mirage-factory address - so we can generate demo data with mirage factories.
  • Model the model - open app/models/address.js and change it to:
import DS from 'ember-data';

export default DS.Model.extend({
  firstName: DS.attr('string'),
  lastName: DS.attr('string'),
  street: DS.attr('string'),
  city: DS.attr('string'),
  country: DS.attr('string')
});

Step 3: Prepare mirage for addresses.

  • Open mirage/factories/address.js and change it to:
import { Factory, faker } from 'ember-cli-mirage';

export default Factory.extend({
  firstName() {
    return faker.name.firstName();
  },
  lastName() {
    return faker.name.lastName();
  },
  street() {
    return faker.address.streetAddress();
  },
  city() {
    return faker.address.city();
  },
  country() {
    return faker.address.country();
  }
});

We are using the fine faker lib to generate some random data. Alternativly you can just enter statics values.

  • Next, change the default scenario in mirage/scenarios/default.js to:
export default function(server) {
  server.createList('address', 20);
}

So mirage generates 20 address entries for us with the given factory settings.

  • Last, we need to define the routes, needed for the CRUD stuff to work. Open mirage/config.js and change it to:
export default function() {
  this.get('/addresses');
  this.get('/addresses/:id');
  this.post('/addresses');
  this.del('/addresses/:id');
  this.patch('/addresses/:id');

Step 4: Show all addresses

  • Create the ember route to display the addresses: ember generate route addresses/index.
  • Open the hbs template and add:
<div class="ui segment">
  <table class="ui table">
    <thead>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Street</th>
      <th>City</th>
      <th>Coutnry</th>
    </thead>
    <tbody>
      {{#each model as |address|}}
        <tr>
          <td>{{address.firstName}}</td>
          <td>{{address.lastName}}</td>
          <td>{{address.street}}</td>
          <td>{{address.city}}</td>
          <td>{{address.country}}</td>
        </tr>
      {{/each}}
    </tbody>
  </table>
</div>
  • Open the route file and change it to:
import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    return this.get('store').findAll('address');
  }
});
  • Head your browser to: http://localhost/addresses to see the result: 20 generated dummy entries in our address table.

  • We add an application template to insert a simple menu: ember g template application

  • with content:

<div class="ui segment">
  <div class="ui menu">
    <div class="header item">
      {{#link-to "index"}}CRUD Tool{{/link-to}}
    </div>

    {{#link-to "addresses" class="item"}}Addresses{{/link-to}}
  </div>
</div>
{{outlet}}

Step 5: create a form component

Cause the form to edit and add new address are the same we make a component out of it:

  • ember g component address-form
  • Change the template content to:
<div class="field">
  <label>First Name</label>
  <div class="ui action input">
    {{input value=model.firstName}}
  </div>
</div>
<div class="field">
  <label>Last Name</label>
  <div class="ui action input">
    {{input value=model.lastName}}
  </div>
</div>
<div class="field">
  <label>Street</label>
  <div class="ui action input">
    {{input value=model.street}}
  </div>
</div>
<div class="field">
  <label>City</label>
  <div class="ui action input">
    {{input value=model.city}}
  </div>
</div>
<div class="field">
  <label>Country</label>
  <div class="ui action input">
    {{input value=model.country}}
  </div>
</div>

Step 6: create the route to add new addresses

  • ember g route addresses/new
  • Change the template to
<div class="ui grid form">
  <div class="sixteen wide column">
    <form {{action 'save' model on='submit'}} >
      <div class="ui segment">
        {{address-form model=model}}
      </div>
      <button type="submit" class="ui primary button">Add address</button>
      {{#link-to 'addresses' }}
        <button class="ui button secondary"><i class="icon chevron left"></i>Go Back</button>
      {{/link-to}}
    </form>
  </div>
</div>
  • And the JS of the route to:
import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    return this.get('store').createRecord('address');
  },

  actions: {
    save(record) {
      record.save()
        .then(() => this.transitionTo('addresses'));
    },

    willTransition() {
      this._super(...arguments);
      const record = this.controller.get('model');
      record.rollbackAttributes();
    }
  }

});
  • Now you can visit http://localhost:4200/addresses/new and add new entries. They will stay until you hit reload.
  • To make navigation a little bit easier, add a "new" button below the table:
{{#link-to 'addresses.new'}}
  <button class="ui primary button">New address</button>
{{/link-to}}

Step 7: Add the edit route

  • create the route, we also specify the path here: ember g route addresses/edit --path=:address_id/edit
  • Add a link to the edit form from the table by changing extending the first name column:
...
          <td>
            {{#link-to 'addresses.edit' address.id}}
              {{address.firstName}}
            {{/link-to}}
          </td>
...
  • Change the edit template to:
<div class="ui grid form">
  <div class="sixteen wide column">
    <form {{action 'save' model on='submit'}} >
      <div class="ui segment">
        {{address-form model=model}}
      </div>
      <button type="submit" class="ui primary button">Change address</button>
      {{#link-to 'addresses' }}
        <button class="ui button secondary"><i class="icon chevron left"></i>Go Back</button>
      {{/link-to}}
    </form>
  </div>
</div>
  • And the Route JS to:
import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    save(record) {
      record.save()
        .then(() => this.transitionTo('addresses'));
    },

    willTransition() {
      this._super(...arguments);
      const record = this.controller.get('model');
      record.rollbackAttributes();
    }
  }

});

Step 9: deletion

  • create the route, we also specify the path here: ember g route addresses/delete --path=:address_id/delete
  • Add a link to the delete form from the table by changing extending the first name column:
...
          <td>
            {{#link-to 'addresses.edit' address.id}}
              {{address.firstName}}
            {{/link-to}}
            {{#link-to 'addresses.delete' address.id}}
              <i class="icon trash"></i>
            {{/link-to}}
          </td>
...
  • Change the delete template to:
<div class="ui segment">
  <form {{action 'confirm' model on='submit'}} >
    <div class="ui warning message">
      <div class="header">
        Are you sure?
      </div>
    </div>
    <button type="submit" class="ui negative button">Delete</button>
    {{#link-to 'addresses' }}
      <button class="ui button secondary icon chevron left">Go Back</button>
    {{/link-to}}
  </form>
</div>
  • And the Route JS to:
import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    confirm(record) {
      record.destroyRecord()
        .then(() => this.transitionTo('addresses'));
    }
  }
});

About

Tutorial app showing ember crud and mirage best practices

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published