0
votes

I have an Ember App where some Models use Ember Data and some don't. My question relates to creating relationships between these Models and also the best way to structure the Model relationships.

Models

Currently I have the following Models:

  • Foods
    • not using Ember Data
    • makes $.ajax request to external API
    • extends a Ember.Object (see here and here for examples of the methodology)
  • Meals
    • uses Ember Data
    • has many Portions
  • Portions
    • uses Ember Data
    • hasOne Meal
    • hasOne Food

In my app I need a Portion to be a unique record which has a weight field. Each Portion should derive it's other values from a associated Food. A Meal should contain many Portions.

Questions

  1. Should Portions be a Model in it's own right our should it be stored in some kind of array-like structure as a field on the Meal (eg: portions)? Consider that a Portion is not reusable and is only able to be associated with a single Meal.
  2. If "Yes" to #1 then what could my Meal Model def look like?
  3. As Food does not use Ember Data what's the best technique for defining a relationship between a Portion and a Food?

Ultimately the User experience should allow someone to

  1. View a Food
  2. Create a Portion of that Food
  3. Associate the Portion with a Meal
  4. View all Portions associated with a Meal

Your help is much appreciated.

1
Is there any particular reason you're not using Ember-Data for the Food model? It seems a little silly that you already have it included and want to connect relationships to it, but don't want to define it as an Ember-Data model.GJK
Well I understood that Ember-Data was based on a REST API endpoint. I don't control the API endpoint (it's 3rd party) and so it was my understanding that this would preclude me from utilising Ember-Data. If you know of a way I could have the best of both worlds then that would be a great help.getdave
Ember-Data has the concept of Adapters, which allow you to customize how it performs CRUD operations on records. If you can access the API using $.ajax, then you can write an Ember-Data adapter to handle it for you. You can also make it so than an adapter only handles one type of model instead of all of them. Take a look at this question for an example.GJK

1 Answers

0
votes

Q1: Should Portions be a Model in it's own right our should it be stored in some kind of array-like structure as a field on the Meal (eg: portions)?

I'm not sure you are asking if Portions should be a model or Portion should be a model. But whatever I think the solution is to build Portion as a model and build portions relationship for Meal model. Because you have functionality to create a portion with a food. In my understanding the portion should be created without a meal (although it can link to a meal later).

Q2: If "Yes" to #1 then what could my Meal Model def look like?

The model definition is like this:

App.Portion = DS.Model.extend({
  weight: DS.attr(),
  meal: DS.belongsTo('meal', {async: true})
});

App.Meal = DS.Model.extend({
  portions: DS.hasMany('portion', {async: true})
});

Q3: As Food does not use Ember Data what's the best technique for defining a relationship between a Portion and a Food?

It's better to still use Ember Data to define Food model, just define your custom adapter and serializer, Ember Data handles the rest. The DS.Adapter and DS.Serializer documentations are good place to start. Below is a simple example.

// Just name it "FoodAdapter" and Ember Data knows to use it for "Food".
App.FoodAdapter = DS.Adapter.extend({
  find: function(store, type, id) {
    // The returned value is passed to "serializer.extract" then "store.push"
    return this._ajax({url: '/external/food', type: 'GET'});
  },

  createRecord: function() {},
  updateRecord: function() {},
  deleteRecord: function() {},
  findAll: function() {},
  findQuery: function() {},

  _ajax: function(options) {
    // Transform jQuery promise to standard promise
    return Em.RSVP.cast($.ajax(options));
  }
});

App.FoodSerializer = DS.Serializer.extend({
  // Assume the json is:
  // {
  //   "food_data": {
  //     "name": "XXX",
  //     "price": 100
  //   }
  // }
  extract: function(store, type, payload, id, requestType) {
    return payload.food_data;
  },

  serialize: function() {}
});