Domanda

I'm creating a cocktail app with the models "cocktail", "membership", and "ingredient". The cocktail and ingredient models are pretty self explanatory and the membership model is for objects that link a cocktail to an ingredient with amount.

App.Cocktail = DS.Model.extend({
  name: DS.attr('string'),
  description: DS.attr('string'),
  created_by: DS.attr('number'),
  start_date: DS.attr('string'),
  end_date: DS.attr('string'),

  // link cocktail to memberships
  membership: DS.hasMany('membership',{ async: true })
});

App.Membership = DS.Model.extend({
  amount: DS.attr('string'),

  // link membership to ingredient and cocktail
  ingredient: DS.belongsTo('ingredient'),
  cocktail: DS.belongsTo('cocktail')
});

App.Ingredient = DS.Model.extend({
  name: DS.attr('string'),
  description: DS.attr('string'),
  start_date: DS.attr('string'),
  end_date: DS.attr('string')
});

The problem I'm having is when I use ember-data to create a cocktail and then its memberships to ingredients the ingredient and cocktail ids for the REST call are strings not ints so the request body looks like this:

{membership:{amount:"2 litres",ingredient:"12",cocktail:"116"}}

when what I want instead:

{membership:{amount:"2 litres",ingredient:12,cocktail:116}}

Here's my code that performs the saving of which I'm pretty new to the idea of promises so not sure if this is structured in the most preferable way.

... code
  actions: {
    // fired when user presses save
    submit: function() {
      // some validation

      var cocktailPromise = this._saveCocktail();
      this._saveIngredientMemberships(cocktailPromise);
    }
  }
... more code
  _saveCocktail: function() {
    console.log('saving cocktail');

    var cocktail = this.store.createRecord('cocktail', {
      name: this.get('cocktailName'),
      description: this.get('cocktailDescription'),
      start_date: "now"
    });

    return cocktail.save();
  },

  _saveIngredientMemberships: function(cocktailPromise) {
    console.log('saving cocktail ingredients');

    // get the ingredients and amounts (memberships) the 
    // user entered and the store and set them as var here 
    // so they stay in scope.
    var memberships = this.get('memberships');
    var store = this.store;

    // once cocktail is created
    cocktailPromise.then(function(cocktail) {
      console.log('cocktail ready, saving ingredients');

      var membershipRecords = [];

      for( var i = 0 ; i < memberships.length ; i++ ) {
        membershipRecords[i] = store.createRecord('membership', {
          cocktail: cocktail,
          ingredient: memberships[i].get('ingredient'),
          amount: memberships[i].get('amount')
        });

        membershipRecords[i].save();
      }

    }, function() {
      console.log('something went wrong saving the cocktail!');
    })
  },
È stato utile?

Soluzione

By default, Ember treats all IDs as strings (it coerces numbers to strings). What you'll want to do is override the RESTSerializer. You can find all of the possible methods to override here. I would advise that you read the source code for the adapter as well. That will really help. It's been a while since I've used Ember-Data, but I believe the method you want to look at is serialize. I would do something like this:

App.ApplicationAdapter = DS.RESTAdapter.extend({
    serialize: function(record, options) {
        var json = this._super(record, options);
        json.ingredient = parseInt(json.ingredient);
        json.cocktail = parseInt(json.cocktail);

        ...

        return json;
    }
});

You can obviously make it more efficient for different models, but you get the idea. You might also be able to override a more specific method, which is why I recommended reading the source code too.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top